zoukankan      html  css  js  c++  java
  • 【NOIP2010提高组】引水入城

    这题。。。
    以前打的,很暴力的bfs:

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int a[502][502],ll[502],rr[502],data[300001][2];
    bool bz[502][502];
    int temp,n,m;
    const int way[5][2]={-1,0,1,0,0,-1,0,1};
    void bfs(int x,int y)
    {
    	int l=0,r=1,i,xx,yy;
    	memset(data,0,sizeof(data));
    	data[1][0]=x;
    	data[1][1]=y;
    	while (l<r)
    	{
    		l++;
    		for (i=0;i<4;i++)
    		{
    			xx=data[l][0]+way[i][0];
    			yy=data[l][1]+way[i][1];
    			if (xx>0&&yy>0&&xx<=n&&yy<=m&&a[xx][yy]<a[data[l][0]][data[l][1]]&&bz[xx][yy]==false)
    			{
    				bz[xx][yy]=true;
    				r++;
    				data[r][0]=xx;data[r][1]=yy;
    			}
    		}
    	}
    }
    void dg(int x,int y)
    {
    	int l=0,r=1,i,xx,yy;
    	memset(data,0,sizeof(data));
    	memset(bz,0,sizeof(bz));
    	data[1][0]=x;
    	data[1][1]=y;
    	while (l<r)
    	{
    		l++;
    		for (i=0;i<4;i++)
    		{
    			xx=data[l][0]+way[i][0];
    			yy=data[l][1]+way[i][1];
    			if (xx>0&&yy>0&&xx<=n&&yy<=m&&a[xx][yy]<a[data[l][0]][data[l][1]]&&bz[xx][yy]==false)
    			{
    				bz[xx][yy]=true;
    				r++;
    				data[r][0]=xx;data[r][1]=yy;
    			}
    		}
    	}
    	for (i=1;i<=m;i++)
    	{
    		if (bz[n][i]==false) continue;
    		if (ll[temp]==0) ll[temp]=i;
    		rr[temp]=i;
    	}
    }
    int main()
    {
    	int i,j,k=0,ans=0;
    	scanf("%d%d",&n,&m);
    	for (i=1;i<=n;i++)
    		for (j=1;j<=m;j++)
    			scanf("%d",&a[i][j]);
    	for (i=1;i<=m;i++) bfs(1,i);
    	for (i=1;i<=m;i++)
    	{
    		if (bz[n][i]==false) k++;
    	}
    	if (n==1)
    	{
    		printf("1
    %d
    ",k);
    	}
    	else if (k>0)
    	{
    		printf("0
    %d
    ",k);
    	}
    	else
    	{
    		for (i=1;i<=m;i++)
    		{
    			temp=i;
    			dg(1,i);
    		}
    		i=1;
    		k=0;
    		while (i<=m)
    		{
    			for (j=1;j<=m;j++)
    			{
    				if (ll[j]<=i&&rr[j]>k) k=rr[j];
    			}
    			i=k+1;
    			ans++;
    		}
    		printf("1
    %d
    ",ans);
    	}
    }
    

    这题其实可以贪心的。
    因为不难发现,第一层要选的有一个条件:

    a[1][i]>a[1][i-1] && a[1][i]>a[1][i+1]

    因为这样才算优嘛。
    然后就是一个性质了:

    它所流到的第n层一定是一段连续的区间。

    如果不是的话,那就输出0吧~

    思考一下,为什么呢?

    因为如果不是一段连续的区间,那么它中间断掉的地方则永远都留不到!

    好了,就说到这里了,自己在想想吧。
    上标:

    #include<cstdio>
    #include<cstring>
    #define min(x,y) x=x<y ? x:y
    #define max(x,y) x=x>y ? x:y
    using namespace std;
    int a[501][501],l[501],r[501],n,m,ans,fr;
    bool bz[501][501],c[501];
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    void dg(int x,int y)
    {
    	bz[x][y]=1;
    	if (x==n) {c[y]=1,min(l[fr],y),max(r[fr],y);}
    	if (y>1 && a[x][y]>a[x][y-1] && !bz[x][y-1]) dg(x,y-1);
    	if (y<m && a[x][y]>a[x][y+1] && !bz[x][y+1]) dg(x,y+1);
    	if (x>1 && a[x][y]>a[x-1][y] && !bz[x-1][y]) dg(x-1,y);
    	if (x<n && a[x][y]>a[x+1][y] && !bz[x+1][y]) dg(x+1,y);
    }
    
    int main()
    {
    	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++) l[i]=m+1;
    	for (int i=1;i<=m;i++)
    	{
    		memset(bz,0,sizeof(bz));
    		if (a[1][i]>=a[1][i-1] && a[1][i]>=a[1][i+1]) fr=i,dg(1,i);
    	}
    	for (int i=1;i<=m;i++) ans+=(!c[i]);
    	if (ans) return 0&printf("0
    %d
    ",ans);
    	for (int i=1,x=0;i<=m;i=x+1,ans++)
    		for (int j=1;j<=m;j++)
    			if (l[j]<=i && r[j]>=x) x=r[j];
    	printf("1
    %d
    ",ans);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    55. 跳跃游戏
    45. 跳跃游戏 II
    对称的二叉树
    字符型图片验证码,使用tensorflow实现卷积神经网络,进行验证码识别CNN
    python版本升级及pip部署方法
    Two Sum [easy] (Python)
    工作中常用的linux命令(持续更新)
    PAT-1001. 害死人不偿命的(3n+1)猜想 (15)
    C++二维数组的动态声明
    19. Remove Nth Node From End of List(C++,Python)
  • 原文地址:https://www.cnblogs.com/jz929/p/11817688.html
Copyright © 2011-2022 走看看