zoukankan      html  css  js  c++  java
  • 2020 ICPC Shanghai B

    题目链接:
    https://vjudge.net/contest/416227#problem/B
    给定扫雷地图A,B,让你改变B中的某些方格,使总共的数字和与A中一致,且改动次数不超过总格数的一半。
    我们可以换一个角度理解数字和:
    我们可以把相邻的格子(相邻指的是有共同的端点)间连无向边,边上有权值
    如果一个雷和一个没有雷的格子相邻,那么权值为1,如果这两个格子都有雷或者都没雷,那权值就为0。对所有的边权求和,结果就是所求的数字和。
    这个角度跟场的势能的概念有点接近
    从这个角度讲,重要的是相邻的两个格子的属性是否相同,给定一种地图,我们可以构造与其属性完全相反的地图,其数字和不变。
    我们要通过改变B中某些格子的属性,使其数字和与A一致,不如构造成A或每个格子与A都相反的地图。
    为了说明这种构造满足动次数不超过总格数的一半,需要证明一下

    我们把A,B映射成两个2进制数x,y,每一位就代表一个格子有雷还是没有雷,设与A相反的图对应z
    定义两个图之间的差异为(w(a,b)=sum_{i=0}^{nm-1}[(a\,xor\,b)\,and\,2^i>0])
    那么(x\,xor\,z=111...111)
    (w(x,y)+w(y,z)=sum_{i=0}^{nm-1}[(x\,xor\,y)\,and\,2^i>0]+sum_{i=0}^{nm-1}[(z\,xor\,y)\,and\,2^i>0]=sum_{i=0}^{nm-1}[(z\,xor\,y)\,and\,2^i>0]+[(x\,xor\,y)\,and\,2^i>0])
    由于(x,z)的每一位都是不同的,因此([(z\,xor\,y)\,and\,2^i>0],[(x\,xor\,y)\,and\,2^i>0])有且仅有一个成立
    (w(x,y)+w(y,z)=nm)
    (min(w(x,y),w(y,z))lefrac{nm}{2})
    所以我们只要构造出A和A的相反图,再和B比较,取差异小的即可
    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    using namespace std;
    char A[1010][1010];
    char B[1010][1010];
    char inv_A[1010][1010];
    char inv(char ch)
    {
    	if(ch=='.')return 'X';
    	return '.';
    }
    int comp(char map1[][1010],char map2[][1010],int n,int m)
    {
    	int ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)
    		{
    			ans+=(map1[i][j]!=map2[i][j]);
    		}
    	}
    	return ans;
    }
    int main()
    {
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%s",A[i]+1);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%s",B[i]+1);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)inv_A[i][j]=inv(A[i][j]);
    	}
    	int comp1=comp(A,B,n,m);
    	if(comp1*2<=n*m)
    	{
    		for(int i=1;i<=n;i++)
    		{
    			printf("%s
    ",A[i]+1);
    		}
    	}
    	else
    	{
    		for(int i=1;i<=n;i++)
    		{
    			printf("%s
    ",inv_A[i]+1);
    		}
    	}
    }
    
  • 相关阅读:
    初涉echarts图表笔记。
    es6----数组去重(简单类型和引用类型)
    git pull 拉取更新失败解决方案
    javascript----是否下拉到页面底部
    构造函数和析构函数
    派生类和基类
    C++11新标准
    类型转换
    编码
    牛牛的背包问题
  • 原文地址:https://www.cnblogs.com/ssdfzhyf/p/14514111.html
Copyright © 2011-2022 走看看