传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5998
经典的开关灯问题,学习到了著名的(但我不知道的)做法
显然如果我们确定了矩阵距离边缘长为5的的那些块的状态,那么整个矩阵也就确定了
所以要想找自由元只需要在这些20*n个点里找就没了
#include<bits/stdc++.h> using namespace std; const int maxn=110; int n,m,k; int dx[10],dy[10]; int mp[maxn][maxn]; long long pw(long long x,long long k){ long long mo=1e9+7; long long ans=1; for(;k;k>>=1){ if(k&1)ans=ans*x%mo; x=x*x%mo; } return ans; } bitset<2000>base[2000]; int N; bool insert(bitset<2000>bs){ for(int i=N;i>=0;i--)if(bs[i]){ if(base[i].any()){ bs=bs^base[i]; }else{ base[i]=bs; return true; } } return false; } int main(){ int T; cin>>T; while(T--){ cin>>n>>m>>k; for(int i=0;i<k;i++) cin>>dx[i]>>dy[i]; N=0; memset(mp,0,sizeof mp); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(i<=5||i>=n-4||j<=5||j>=m-4){ mp[i][j]=++N; } } } for(int i=0;i<=N;i++) base[i].reset(); int cnt=0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++)if(mp[i][j]){ bitset<2000>bs; bs[mp[i][j]]=1; bs[0]=1; for(int l=0;l<k;l++){ int x=i+dx[l]; int y=j+dy[l]; if(x<1||x>n||y<1||y>m)continue; if(mp[x][y]) bs[mp[x][y]]=bs[mp[x][y]]^1; } if(!insert(bs)) cnt++; } } long long ans=pw(2,cnt); cout<<ans<<endl; } return 0; }
hack:
1
5 5 5
2 2
-1 -3
4 -2
2 2
-4 2
嗯……非常抱歉……我人脑无法处理这组数据……
我觉得问题可能出在那两个2 2 上?
如果有标程的话请联系我 ^_^ 谢谢