[BZOJ 3503][Cqoi 2014]和谐矩阵

我觉得这一题的样例输出一点都不和谐,大家千万别像我一样被坑了……

题目不算难,果然是进错省系列555,不过搞出 O(n*m*2m) 的还是不要挣扎的比较好

我们暴力地推出第 n 行 第 m 列中每个数是第 1 行的哪些数的 nim 和 ——O(n3)

然后再算出 b[j] = a[n][j] xor a[n-1][j] xor a[n][j+1] xor a[n][j-1]

就有了一个似是而非的一个抑或方程组,因为如果去解的话结果一定是 xi=0

怎么办呢?

既然题目说一定有解,必然存在一个 xi=1 , 我们就暴力枚举!然后尝试解方程组即可 ——O(n4)

 

  1 #include <cstdio>

  2 #include <cstring>

  3 const int sizeOfMatrix=42;

  4 

  5 int m, n;

  6 inline int getint();

  7 inline void putint(bool);

  8 

  9 struct node

 10 {

 11     bool a[sizeOfMatrix];

 12     inline node() {memset(a, 0, sizeof(a));}

 13     inline bool & operator [] (int x) {return a[x];}

 14 };

 15 inline node operator ^ (node a, node b)

 16 {

 17     node c;

 18     for (int i=1;i<=n;i++) c[i]=a[i]^b[i];

 19     return c;

 20 }

 21 

 22 node a[sizeOfMatrix][sizeOfMatrix];

 23 node f[sizeOfMatrix];

 24 bool b[sizeOfMatrix][sizeOfMatrix];

 25 bool x[sizeOfMatrix];

 26 inline void swap(bool & , bool & );

 27 inline bool solve(int);

 28 inline bool calc(int, int);

 29 

 30 int main()

 31 {

 32     m=getint(), n=getint();

 33     for (int i=1;i<=n;i++) a[1][i][i]=true;

 34     for (int i=2;i<=m;i++)

 35         for (int j=1;j<=n;j++)

 36             a[i][j]=a[i-1][j]^a[i-1][j-1]^a[i-1][j+1]^a[i-2][j];

 37     for (int i=1;i<=n;i++)

 38         f[i]=a[m][i]^a[m][i-1]^a[m][i+1]^a[m-1][i];

 39 

 40     for (int i=1;i<=n;i++)

 41         if (solve(i))

 42             break;

 43 

 44     for (int i=1;i<=m;i++)

 45     {

 46         for (int j=1;j<=n;j++)

 47             putint(calc(i, j));

 48         putchar('\n');

 49     }

 50 

 51     return 0;

 52 }

 53 inline int getint()

 54 {

 55     register int num=0;

 56     register char ch;

 57     do ch=getchar(); while (ch<'0' || ch>'9');

 58     do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');

 59     return num;

 60 }

 61 inline void putint(bool num)

 62 {

 63     if (num) putchar('1');

 64     else putchar('0');

 65     putchar(' ');

 66 }

 67 inline void swap(bool & a, bool & b)

 68 {

 69     bool t=a; a=b; b=t;

 70 }

 71 inline bool solve(int k)

 72 {

 73     for (int i=1;i<=n;i++)

 74     {

 75         for (int j=1;j<=n;j++)

 76             b[i][j]=f[i][j];

 77         if (f[i][k]==true)

 78             b[i][k]=false, b[i][n+1]=true;

 79     }

 80     for (int i=1;i<=n;i++)

 81     {

 82         if (!b[i][i])

 83         {

 84             for (int j=i+1;j<=n;j++) if (b[j][i])

 85             {

 86                 for (int k=1;k<=n+1;k++)

 87                     swap(b[j][k], b[i][k]);

 88                 break;

 89             }

 90         }

 91 

 92         if (!b[i][i]) continue;

 93 

 94         for (int j=i+1;j<=n;j++) if (b[j][i])

 95             for (int k=i;k<=n+1;k++)

 96                 b[j][k]^=b[i][k];

 97     }

 98 

 99     x[k]=true;

100     for (int i=n;i>=1;i--)

101     {

102         if (!b[i][i]) continue;

103         x[i]=b[i][n+1];

104         for (int j=n-1;j>=1;j--) if (b[j][i])

105             b[j][i]=false, b[j][n+1]^=x[i];

106     }

107 

108     for (int i=1;i<=n;i++)

109     {

110         bool check=false;

111         for (int j=1;j<=n;j++) if (f[i][j])

112             check^=x[j];

113         if (check) return false;

114     }

115 

116     return true;

117 }

118 inline bool calc(int i, int j)

119 {

120     bool ans=false;

121     for (int k=1;k<=n;k++) if (a[i][j][k])

122         ans^=x[k];

123     return ans;

124 }
我的心已片片飘落

 

你可能感兴趣的:(ZOJ)