• 【CF1567F】One-Four Overload


    题目

    题目链接:https://codeforces.com/contest/1567/problem/F
    一张 (n imes m) 的网格,网格上有 .X。保证所有 X 都不与网格边缘相邻。给 . 赋值为 (1)(4)X 赋值为 (0,5)(10),求任意一种方案,使得每一个 X 的权值都等于它相邻的 . 权值之和。
    (n,mleq 500)

    思路

    很显然只有当 X 四周有偶数个 . 才有解。
    如果 X 周围只有两个 .,那么直接把这两个 . 连边,然后黑白染色即可。
    如果 X 周围有四个 .,猜了一个结论:存在一个上下两个 . 权值相同,左右两个 . 权值相同的解。
    手玩了一下感性理解的。我也不知道怎么证((。官方题解没看。
    时间复杂度 (O(nm))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=510,M=1000010;
    const int dx[]={0,0,0,1,-1},dy[]={0,1,-1,0,0};
    int n,m,tot,a[N][N],b[M],head[M],pos[3];
    bool flag;
    char ch;
    
    struct edge
    {
    	int next,to;
    }e[M];
    
    int ID(int x,int y)
    {
    	return (x-1)*m+y;
    }
    
    void add(int from,int to)
    {
    	e[++tot]=(edge){head[from],to};
    	head[from]=tot;
    	swap(from,to);
    	e[++tot]=(edge){head[from],to};
    	head[from]=tot;
    }
    
    void dfs(int x,int val)
    {
    	b[x]=val;
    	for (int i=head[x];~i;i=e[i].next)
    	{
    		int v=e[i].to;
    		if (!b[v]) dfs(v,5-val);
    		if (b[x]==b[v]) flag=1;
    		if (flag) return;
    	}
    }
    
    int main()
    {
    	memset(head,-1,sizeof(head));
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    		{
    			while (ch=getchar())
    				if (ch=='.' || ch=='X') break;
    			if (ch=='X') a[i][j]=1;
    		}
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			if (a[i][j])
    			{
    				int sum=4;
    				for (int k=1;k<=4;k++) 
    					sum-=a[i+dx[k]][j+dy[k]];
    				if (sum&1) return printf("NO"),0;
    				if (sum==2)
    				{
    					int tp=0;
    					for (int k=1;k<=4;k++)
    						if (!a[i+dx[k]][j+dy[k]]) pos[++tp]=ID(i+dx[k],j+dy[k]);
    					add(pos[1],pos[2]);
    				}
    				if (sum==4)
    				{
    					add(ID(i-1,j),ID(i,j-1)); add(ID(i-1,j),ID(i,j+1));
    					add(ID(i+1,j),ID(i,j-1)); add(ID(i+1,j),ID(i,j+1));
    				}
    			}
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			if (!a[i][j] && !b[ID(i,j)]) dfs(ID(i,j),1);
    	if (flag) return printf("NO"),0;
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			if (a[i][j])
    				for (int k=1;k<=4;k++)
    				{
    					int x=i+dx[k],y=j+dy[k];
    					if (!a[x][y]) b[ID(i,j)]+=b[ID(x,y)];
    				}
    	cout<<"YES
    ";
    	for (int i=1;i<=n;i++)
    	{
    		for (int j=1;j<=m;j++)
    			cout<<b[ID(i,j)]<<" ";
    		cout<<"
    ";
    	}
    	return 0;
    }
    
  • 相关阅读:
    神奇的python系列10:函数(三)
    神奇的python系列9:函数(二)
    神奇的python系列8:函数(一)
    神奇的python系列7:文件操作
    神奇的python系列6:python基础数据类型补充
    神奇的python系列5:python基础数据类型三(字典)
    神奇的python系列4:python基础数据类型二(列表)
    神奇的python系列3:python基础数据类型一
    神奇的python系列2:python基础一
    Token机制,session机制
  • 原文地址:https://www.cnblogs.com/stoorz/p/15232424.html
Copyright © 2020-2023  润新知