比赛 练习12 评测结果 AAAAAAAAAA
题目名称 引水入城 最终得分 100
用户昵称 NVIDIA 运行时间 0.049 s
代码语言 C++ 内存使用 0.31 MiB
提交时间 2017-06-30 13:46:02
显示代码纯文本
/*
NAME:槿柒
LANG:C++
TIME:0.5S
PID:4819
*/
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
inline int read()
{
	int x,f=1;char ch;
	while(ch=getchar(),!isdigit(ch))if(ch=='-')f=-1;x=ch-48;
	while(ch=getchar(),isdigit(ch))x=x*10+ch-48;return x*f;
}
const int maxn=510;
int n,m,a[maxn][maxn],l[maxn],r[maxn],f[maxn],dx[5]={0,0,1,-1},dy[5]={1,-1,0,0};//f[i]:表示到第n行第i列所建的最小蓄水厂 
bool flag[maxn][maxn],vis[maxn];
inline void Dfs(int s,int x,int y){
	if(x==n){
		vis[y]=1;//记录总深搜能搜到的点,不可清空 
		if(!l[s]||l[s]>y)l[s]=y;//l[s]表示如果以s建立蓄水厂,能扩展的左边界的最大值 
		if(r[s]<y)r[s]=y;//同理,r[s]表示如果以s建立蓄水厂,能扩展的右边界的最大值 
	}
	flag[x][y]=1;
	for(int i=0;i<4;i++){
		int xx=x+dx[i],yy=y+dy[i];//传说中的floodfill…… 
		if(xx<1||xx>n||yy<1||yy>m)continue;
		if(!flag[xx][yy] && a[xx][yy]<a[x][y])Dfs(s,xx,yy);
	}
}
inline int Nymph()
{
	freopen("flow.in","r",stdin);
	freopen("flow.out","w",stdout);
	n=read();m=read();
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)a[i][j]=read();
	for(int i=1;i<=m;i++){
		if(a[1][i]<a[1][i-1])continue;//剪枝,不然会暴。如果当前点高度<之前一列的点,那么它的水直接由i-1转移来,不必再搜索了 
		if(a[1][i]<a[1][i+1])continue;
		memset(flag,0,sizeof(flag));//注意清空~ 
		Dfs(i,1,i);//第一问:深搜即可,dfs(i,1,i)代表如果第i个建蓄水厂,当前坐标为(1,i) 
	}
	int cnt=0;
	for(int i=1;i<=m;i++)if(vis[i])cnt++;
	if(cnt<m){
		printf("0\n%d\n",m-cnt);return 0;
	}
	printf("1\n");
	for(int i=1;i<=m;i++){	//枚举第一行如果i建蓄水厂 
		for(int j=l[i];j<=r[i];j++){	//枚举以i建蓄水厂能伸展的左右边界 
			if(!f[j])f[j]=f[l[i]-1]+1;//预处理 
			else f[j]=min(f[j],f[l[i]-1]+1);//由最左列前面一列转移过来的最小蓄水厂值+1所得的答案与本身比较 
		}
	}
	printf("%d\n",f[m]);
}
int nymph=Nymph();
int main(){;}