zoukankan      html  css  js  c++  java
  • Bzoj3517 翻硬币题解 解异或方程组

    3517: 翻硬币

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 281  Solved: 211
    [Submit][Status][Discuss]

    Description

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

    Input

    第一行包含一个正整数n
    接下来n行,每行包含一个长度为n的01字符串,表示棋盘上硬币的状态。

    Output

    仅包含一行,为最少需要的操作数。

    Sample Input

    4
    0101
    1000
    0010
    0101

    Sample Output

    2

    HINT

    【样例说明】

    对(2,3)和(3,1)进行操作,最后全变成1。

    【数据规模】

    对于100%的数据,n ≤ 1,000。

       上来一看,第一反应,异或数学题,想了半天如何异或也没想出来,问呵呵酵母菌,他说他觉得是图论WTF?!图论有几个O(n)算法能在这道题用上的。

      于是乎看了一眼题解:解异或方程组……

      一个点最多翻一遍,这话不用再说了吧……

      让我们先从都翻为0开始说起

      我们设x[i][j]为第i,j个点是否要翻,a[i][j]为该点初始状态,则x[1][j]^x[2][j]^……^x[n][j]^x[i][1]^x[i][2]^x[i][m]^x[i][j]=a[i][j]。

      我们把第i行和第j列所有的点按照上式列出方程组并合并, 由于n为偶数,则可以化为:

        x[i][j]=a[1][j]^a[2][j]^……^a[n][j]^a[i][1]^a[i][2]^……^a[i][m]^a[i][j]。

      那么我们只要对于每一行,每一列n^2预处理出他们的异或和再相加就好了。

      至于都为1吗?由于n是偶数,我们只要把每一个点是否翻的状态取反就是答案。

     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <queue>
     6 #include <algorithm>
     7 #include <cmath>
     8 #include <map>
     9 #define N 1005
    10 using namespace std;
    11 int n,a[N][N];
    12 char b[N];
    13 int sum[2][N];
    14 int main()
    15 {
    16     scanf("%d",&n);
    17     for(int i=1;i<=n;i++)
    18     {
    19         scanf("%s",b+1);
    20         for(int j=1;j<=n;j++)
    21         {
    22             a[i][j]=b[j]-'0';
    23         }
    24     }
    25     for(int i=1;i<=n;i++)
    26     {
    27         for(int j=1;j<=n;j++)
    28         {
    29             sum[0][i]^=a[i][j];
    30             sum[1][j]^=a[i][j];
    31         }
    32     }
    33     int ans=0;
    34     for(int i=1;i<=n;i++)
    35     {
    36         for(int j=1;j<=n;j++)
    37         {
    38             int t=sum[0][i]^sum[1][j];
    39             t^=a[i][j];
    40             ans+=t;
    41         }
    42     }
    43     ans=min(ans,n*n-ans);
    44     printf("%d
    ",ans);
    45     return 0;
    46 }
    View Code
  • 相关阅读:
    洛谷 P2473 [SCOI2008]奖励关(状压dp+期望)
    洛谷P2051 [AHOI2009]中国象棋(dp)
    洛谷P2523 [HAOI2011]Problem c(计数dp)
    牛客Wannafly挑战赛26E 蚂蚁开会(树链剖分+线段树)
    POJ1149 PIGS
    CF802C Heidi and Library (hard)
    struts中请求数据自动封装
    struts 中数据处理的3中方式
    ajax第二天学习
    jstl标签
  • 原文地址:https://www.cnblogs.com/liutianrui/p/7674354.html
Copyright © 2011-2022 走看看