zoukankan      html  css  js  c++  java
  • bzoj3517 翻硬币

    题意

    有一个n行n列的棋盘,每个格子上都有一个硬币,且n为偶数。每个硬币要么是正面朝上,要么是反面朝上。每次操作你可以选定一个格子(x,y),然后将第x行和第y列的所有硬币都翻面。求将所有硬币都变成同一个面最少需要的操作数。n<=1000.

    分析

    guozizheng?guozizheng!
    操作次数最少,那么每个位置操作次数为0次或1次.
    全变成0的方案完全取反(操作变成不操作,不操作变成操作)就得到了全变成1的方案.(影响位置(i,j)的位置有一行一列共2n-1个,为奇数个,全部取反之后异或和一定会变)
    x[i][j]表示第i行j列的硬币是否被操作一次(x[i]][j]=0表示没有被操作一次,x[i][j]=1表示被操作了一次).那么对于每个硬币可以列出一个异或方程.然后注意一下这些方程的特征,手动解一下.把第i行和第j列的2
    n-1个方程都异或起来可以求出x[i][j].

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=1005;
    int sumx[maxn],sumy[maxn];
    int a[maxn][maxn];
    int read(){
      char ch;while(ch=getchar(),ch!='0'&&ch!='1');
      return ch-'0';
    }
    int main(){
      int n;scanf("%d",&n);
      for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
          a[i][j]=read();
          sumx[i]^=a[i][j];sumy[j]^=a[i][j];
        }
      }
      int ans=0;
      for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
          ans+=(sumx[i]^sumy[j]^a[i][j]^1);
      printf("%d
    ",min(ans,n*n-ans));
      return 0;
    }
    
  • 相关阅读:
    NHibernate 转载
    net中Json对单引号和特殊字符串的处理
    C#过滤非法字符
    Linq Distinct 扩展
    (转)Windows启动过程分析预引导
    special content filetypes require specialized software to use
    存储器
    (转)MAPISendMail调用系统默认的邮件客户端发邮件
    FrameControllerModel
    (转)c++的四种类型转换
  • 原文地址:https://www.cnblogs.com/liu-runda/p/7536782.html
Copyright © 2011-2022 走看看