您的位置:首页 > 其它

A1488. 魔法波(乔明达)

2015-12-11 10:17 218 查看
设si表示表示每个格子的状态(1表示腐地,0表示土地),xi表示对每个格子的操作状态(1表示发射,0表示不发射),可以列出异或方程si^sigma(xj)=1

然而介四O(n^6),BOOM

于是我们把格子分成横向(Yl)和纵向(Yr)的块,每一个块代表能对其中的格子产生影响的格子的集合,所以我们有,,,这里请把sigma理解为异或和

  Y=sigma(xi)          ①

  si^sigma(Ylj)^sigma(Yrj)^xi=1  ②

把②移项得xi=si^sigma(Ylj)^sigma(Yrj)^1  ③

把③带入①得sigma(Ylj)^sigma(Yrj)=Yi^sigma(sj)^sigma(1)   ④

然而只能A50%,内心崩溃

#include<bits/stdc++.h>
using namespace std;
#define maxn 805
bitset<2005>B[2005];
char Map[maxn][maxn];
int num,Yl[maxn][maxn],Yr[maxn][maxn],ans[2005];
void gauss() {
int i, j, k;
for(i=0,k=0; i<num; i++) {
for(j=k; j<num; j++) {
if(B[j][i]==1) {
if(j!=k) swap(B[j],B[k]);
break;
}
}
if(j==num) continue;
for(j=k+1; j<num; j++) {
if(B[j][i]==1) {
B[j] ^= B[k];
}
}
k ++;
}
for(i=0; i<num; i++) ans[i] = -1;
for(i=num-1; i>=0; i--) {
int res = B[i][num];
for(j=num-1; j>=i; j--) {
if(B[i][j]) {
if(ans[j]<0) ans[j] = res;
res ^= ans[j];
}
}
}
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%s",Map[i]+1);
for(int j=1;j<=n;j++){
Map[0][j]='X';
for(int i=1;i<=n;i++){
if(Map[i][j]=='X')continue;
if(Map[i-1][j]=='X')Yr[i][j]=num++;
else Yr[i][j]=Yr[i-1][j];
}
}
for(int i=1;i<=n;i++){
Map[i][0]='X';
for(int j=1;j<=n;j++){
if(Map[i][j]=='X')continue;
if(Map[i][j-1]=='X')Yl[i][j]=num++;
else Yl[i][j]=Yl[i][j-1];
}
}

for(int i=0;i<num;i++)B[i].set(i);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(Map[i][j]=='X')continue;
int l=Yl[i][j],r=Yr[i][j],x=Map[i][j]-'0';
B[l].flip(l),B[l].flip(r);
B[r].flip(l),B[r].flip(r);
if(x^1)B[l].flip(num),B[r].flip(num);
}
for(int i=0;i<num;i++){
for(int j=0;j<=num;j++)
printf("%d",B[i][j]?1:0);
printf("\n");
}
printf("\n");
gauss();
for(int i=0;i<num;i++){
for(int j=0;j<=num;j++)
printf("%d",B[i][j]?1:0);
printf("\n");
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(Map[i][j]=='X')printf("0");
else printf("%d",(Map[i][j]-'0')^ans[Yl[i][j]]^ans[Yr[i][j]]^1);
}
printf("\n");
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: