[TS-A1488][2013中国国家集训队第二次作业]魔法波[高斯消元]

暴力直接解异或方程组,O(n^6)无法接受,那么我们考虑把格子分块,横着和竖着分别分为互不影响的块,这样因为障碍物最多不超过200个,那么块的个数最多为2*(800+200)=2000个,最后用bitset优化即可。

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 int n,cnt,Pos[2100],Right[2100],Left[2100];
  6 int Crs[1100][1100],Dwn[1100][1100],MID;
  7 char    str[1100][1100];
  8 
  9 bitset<2100>eq[2100];
 10 
 11 void    Gauss()
 12 {
 13     int i,j;
 14     for(i=1;i<=cnt;++i)
 15     {
 16         j=i;
 17         while(!eq[j][i] && j<=cnt)j++;
 18         if(j==cnt+1)continue;
 19         if(j!=i)swap(eq[j],eq[i]);
 20         for(j=1;j<=cnt;++j)
 21             if(j!=i && eq[j][i])eq[j]^=eq[i];
 22     }
 23     return ;
 24 }
 25 
 26 int main()
 27 {
 28     int i,j,temp;
 29 
 30     scanf("%d",&n);
 31 
 32     for(i=1;i<=n;++i)
 33         scanf("%s",str[i]+1);
 34 
 35     for(i=1;i<=n;++i)
 36         str[0][i]=str[i][0]=str[i][n+1]=str[n+1][i]='X';
 37 
 38     cnt=1;
 39 
 40     for(j=1;j<=n;++j) for(i=1;i<=n+1;++i)
 41     {
 42         if(str[i][j]!='X')Crs[i][j]=cnt;
 43         if(str[i-1][j]=='X' && str[i][j]!='X')Left[cnt]=i,Pos[cnt]=j;
 44         if(str[i+1][j]=='X' && str[i][j]!='X')Right[cnt]=i,cnt++;
 45     }
 46 
 47     MID=cnt-1;
 48     
 49     for(i=1;i<=n;++i) for(j=1;j<=n+1;++j)
 50     {
 51         if(str[i][j]!='X')Dwn[i][j]=cnt;
 52         if(str[i][j-1]=='X' && str[i][j]!='X')Left[cnt]=j,Pos[cnt]=i;
 53         if(str[i][j+1]=='X' && str[i][j]!='X')Right[cnt]=j,cnt++;
 54     }
 55 
 56     cnt--;
 57 
 58     for(i=1;i<=MID;++i)
 59     {
 60         temp=0;
 61         eq[i].set(i);
 62 
 63         for(j=Left[i];j<=Right[i];++j)
 64         {
 65             eq[i][Crs[j][Pos[i]]]=eq[i][Crs[j][Pos[i]]]^1;
 66             eq[i][Dwn[j][Pos[i]]]=eq[i][Dwn[j][Pos[i]]]^1;
 67             temp^=(str[j][Pos[i]]=='X'?0:str[j][Pos[i]]-48);
 68             temp^=1;
 69         }
 70 
 71         eq[i][cnt+1]=temp;
 72 #ifdef  Debug
 73         cerr << eq[i] << endl;
 74 #endif
 75     }
 76 
 77     for(i=MID+1;i<=cnt;++i)
 78     {
 79         temp=0;
 80         eq[i].set(i);
 81 
 82         for(j=Left[i];j<=Right[i];++j)
 83         {
 84             eq[i][Crs[Pos[i]][j]]=eq[i][Crs[Pos[i]][j]]^1;
 85             eq[i][Dwn[Pos[i]][j]]=eq[i][Dwn[Pos[i]][j]]^1;
 86             temp^=(str[Pos[i]][j]=='X'?0:str[Pos[i]][j]-48);
 87             temp^=1;
 88         }
 89 
 90         eq[i][cnt+1]=temp;
 91 #ifdef  Debug
 92         cerr << eq[i] << endl;
 93 #endif
 94     }
 95 
 96     Gauss();
 97 
 98 #ifdef  Debug
 99     cerr << endl;
100     for(i=1;i<=cnt;++i)
101         cerr << eq[i] << endl;
102     cerr << endl;
103 #endif
104 
105     for(i=1;i<=n;++i)
106     {
107         for(j=1;j<=n;++j)
108         {
109             printf("%d",str[i][j]=='X'?0:(1^eq[Crs[i][j]][cnt+1]^eq[Dwn[i][j]][cnt+1]
110                         ^(str[i][j]-48)));
111         }
112         printf("
");
113     }
114 
115     return 0;
116 }
原文地址:https://www.cnblogs.com/Gster/p/5090516.html