poj 1222 高斯肖元模版题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=30;
int a[maxn][maxn+1],x[maxn];
int equ,var,free_num;
void Debug()
{
for(int i=0;i<equ;i++)
{
for(int j=0;j<var+1;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}
int gcd(int a,int b)
{
if(a<0) return gcd(-a,b);
if(b<0) return gcd(a,-b);
return b==0?a:gcd(b,a%b);
}
int Gauss()
{
int k,col=0;
for(k=0;k<equ&&col<var;k++,col++)
{
int mx=k;
for(int i=k+1;i<equ;i++)
if(a[i][col]>a[mx][col]) mx=i;
if(mx!=k)
for(int i=k;i<var+1;i++) swap(a[k][i],a[mx][i]);
if(!a[k][col]) { k--;continue; }
for(int i=k+1;i<equ;i++)
if(a[i][col]!=0)
{
int lcm=a[k][col]/gcd(a[k][col],a[i][col])*a[i][col];
int ta=lcm/a[i][col],tb=lcm/a[k][col];
if(a[i][col]*a[k][col] < 0) tb = -tb;
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta)%2 - (a[k][j]*tb)%2+2)%2;
}
}
// Debug();
//cout<<col<<endl<<endl;
for(int i=k;i<equ;i++)
if(a[i][var]) return -1;
for(int i=0,j;i<equ;i++)
if(!a[i][i])
{
for(j=i+1;j<var;j++)
if(a[i][j]) break;
if(var==j) break;
for(int r=0;r<equ;r++) swap(a[r][i],a[r][j]);
}
for(int i=k-1;i>=0;i--)
{
int tmp=a[i][var]%2;
for(int j=i+1;j<var;j++)
if(a[i][j]) tmp=(tmp-a[i][j]*x[j]%2+2)%2;
x[i]=(tmp/a[i][i])%2;
}
}
void init()
{
memset(a,0,sizeof(a));
memset(x,0,sizeof(x));
for(int i=0;i<5;i++)
for(int j=0;j<6;j++)
{
if(i!=0) a[i*6+j][(i-1)*6+j]=1;
if(i!=4) a[i*6+j][(i+1)*6+j]=1;
if(j!=0) a[i*6+j][i*6+j-1]=1;
if(j!=5) a[i*6+j][i*6+j+1]=1;
a[i*6+j][i*6+j]=1;
}
}
int main(int argc, char *argv[])
{
int T,ca=1;
scanf("%d",&T);
equ=30,var=30;
while(T--)
{
init();
for(int i=0;i<30;i++) scanf("%d",&a[i][30]);
Gauss();
printf("PUZZLE #%d\n",ca++);
for(int i=0;i<30;i++)
{
if(i%6!=0) putchar(' ');
printf("%d",x[i]);
if(i%6==5) puts("");
}
}
return EXIT_SUCCESS;
}
高斯肖元后,用二进制位枚举自由元,取最优值
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int inf=0x3fffffff;
const int maxn=15*15;
int a[maxn][maxn+1],x[maxn],equ,var,n;
char s[20][20];
void init()
{
equ=var=n*n;
for(int i=0;i<n;i++)
scanf("%s",s[i]);
memset(a,0,sizeof(a));
for(int i=0;i<var;i++) a[i][var]= (s[i/n][i%n]!='y'),a[i][i]=1;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(i!=0) a[(i-1)*n+j][i*n+j]=1;
if(i!=n-1) a[(i+1)*n+j][i*n+j]=1;
if(j!=0) a[i*n+j-1][i*n+j]=1;
if(j!=n-1) a[i*n+j+1][i*n+j]=1;
}
}
void debug()
{
for(int i=0;i<equ;i++)
{
for(int j=0;j<=var;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}
int gcd(int a,int b)
{
if(a<0) return gcd(-a,b);
if(b<0) return gcd(a,-b);
return b==0?a:gcd(b,a%b);
}
int gauss()
{
int k,col;
for(k=col=0;k<equ&&col<var;k++,col++)
{
int mx=k;
for(int i=k+1;i<equ;i++)
if(a[i][col]>a[mx][col]) mx=i;
if(k!=mx){
for(int i=k;i<var+1;i++)
swap(a[k][i],a[mx][i]);
}
if(!a[k][col]){
k--;continue;
}
for(int i=k+1;i<equ;i++)
if(a[i][col])
{
int lcm=a[k][col]/gcd(a[k][col],a[i][col])*a[i][col];
int ta=lcm/a[i][col],tb=lcm/a[k][col];
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta-a[k][j]*tb)%2+2)%2;
}
}
// debug();
for(int i=k;i<equ;i++)
if(a[i][col]) return inf;
for(int i=0,j;i<equ;i++)
if(!a[i][i])
{
for(j=i+1;j<var;j++)
if(a[i][j]) break;
if(j>=var) break;
for(int r=0;r<equ;r++) swap(a[r][i],a[r][j]);
}
int ret=inf,lim= (1<<(var-k));
for(int j=0;j<lim;j++)
{
for(int i=0;i<(var-k);i++)
if(j&(1<<i)) x[equ-1-i]=1;
else x[equ-1-i]=0;
for(int i=k-1;i>=0;i--)
{
int tmp=a[i][var];
for(int j=i+1;j<var;j++)
tmp=((tmp-a[i][j]*x[j])%2+2)%2;
x[i]=tmp/a[i][i]%2;
}
int cnt=0;
for(int i=0;i<var;i++)
if(x[i]) cnt++;
ret=min(cnt,ret);
if(ret==0) break;
}
return ret;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
init();
// debug();
int re=gauss();
//cout<<re<<endl;
if(re==inf) puts("inf");
else printf("%d\n",re);
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=30;
const int inf=0x3fffffff;
int a[maxn][maxn+1],x[maxn];
int equ,var,free_num;
void Debug()
{
for(int i=0;i<equ;i++)
{
for(int j=0;j<var+1;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}
int gcd(int a,int b)
{
if(a<0) return gcd(-a,b);
if(b<0) return gcd(a,-b);
return b==0?a:gcd(b,a%b);
}
int Gauss()
{
int k,col=0;
for(k=0;k<equ&&col<var;k++,col++)
{
int mx=k;
for(int i=k+1;i<equ;i++)
if(a[i][col]>a[mx][col]) mx=i;
if(mx!=k)
for(int i=k;i<var+1;i++) swap(a[k][i],a[mx][i]);
if(!a[k][col]) { k--;continue; }
for(int i=k+1;i<equ;i++)
if(a[i][col]!=0)
{
int lcm=a[k][col]/gcd(a[k][col],a[i][col])*a[i][col];
int ta=lcm/a[i][col],tb=lcm/a[k][col];
if(a[i][col]*a[k][col] < 0) tb = -tb;
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta)%2 - (a[k][j]*tb)%2+2)%2;
}
}
// Debug();
//cout<<col<<endl<<endl;
for(int i=k;i<equ;i++)
if(a[i][var]) return inf;
for(int i=0,j;i<equ;i++)
if(!a[i][i])
{
for(j=i+1;j<var;j++)
if(a[i][j]) break;
if(var==j) break;
for(int r=0;r<equ;r++) swap(a[r][i],a[r][j]);
}
int Min=inf;
for(int j=0;j<(1<<(equ-k));j++)
{
int tmp=j,p=equ-1;
while(tmp) x[p--]=tmp%2,tmp>>=1;
for(int i=k-1;i>=0;i--)
{
int tmp=a[i][var]%2;
for(int j=i+1;j<var;j++)
if(a[i][j]) tmp=(tmp-a[i][j]*x[j]%2+2)%2;
x[i]=(tmp/a[i][i])%2;
}
tmp=0;
for(int i=0;i<16;i++) tmp+=x[i];
Min=min(Min,tmp);
}
return Min;
}
char s[10][10];
int init(int id)
{
memset(a,0,sizeof(a));
memset(x,0,sizeof(x));
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(i!=0) a[i*4+j][(i-1)*4+j]=1;
if(i!=3) a[i*4+j][(i+1)*4+j]=1;
if(j!=0) a[i*4+j][i*4+j-1]=1;
if(j!=3) a[i*4+j][i*4+j+1]=1;
a[i*4+j][i*4+j]=1;
}
if(!id){
if(scanf("%s",s[0])==-1) return 0;
for(int i=1;i<4;i++) scanf("%s",s[i]);
}
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
a[i*4+j][16]=id^(s[i][j]=='w');
return 1;
}
int main()
{
equ=16,var=16;
while(init(0))
{
//Debug();
int ans=Gauss();
init(1);
ans=min(ans,Gauss());
if(ans!=inf) printf("%d\n",ans);
else printf("Impossible\n");
}
return EXIT_SUCCESS;
}
和上面几乎一样的题目
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=20;
const int inf=0x3fffffff;
int a[maxn][maxn+1],x[maxn],equ,var;
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
void debug()
{
for(int i=0;i<equ;i++)
{
for(int j=0;j<var+1;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}
int gauss()
{
int k,col;
for(k=col=0;k<equ&&col<var;k++,col++)
{
int mx=k;
for(int i=k+1;i<equ;i++)
if(a[i][col]>a[mx][col]) mx=i;
if(k!=mx){
for(int i=k;i<var+1;i++)
swap(a[k][i],a[mx][i]);
}
if(!a[k][col]){
k--;continue;
}
for(int i=k+1;i<equ;i++)
if(a[i][col])
{
int lcm=a[k][col]/gcd(a[k][col],a[i][col])*a[i][col];
int ta=lcm/a[i][col],tb=lcm/a[k][col];
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta-a[k][j]*tb)%2+2)%2;
}
}
// debug();
for(int i=k;i<equ;i++)
if(a[i][col]) return -1;
for(int i=0,j;i<equ;i++)
if(!a[i][i])
{
for(j=i+1;j<var;j++)
if(a[i][j]) break;
if(j>=var) break;
for(int r=0;r<equ;r++)
swap(a[r][i],a[r][j]);
}
int ret=inf,lim= (1<<(var-k));
for(int j=0;j<lim;j++)
{
for(int i=0;i<(var-k);i++)
if(j&(1<<i)) x[equ-1-i]=1;
else x[equ-1-i]=0;
for(int i=k-1;i>=0;i--)
{
int tmp=a[i][var];
for(int j=i+1;j<var;j++)
tmp=((tmp-a[i][j]*x[j])%2+2)%2;
x[i]=tmp/a[i][i]%2;
}
int cnt=0;
for(int i=0;i<var;i++)
if(x[i]) cnt++;
ret=min(cnt,ret);
if(ret==0) break;
}
return ret;
}
int main()
{
var=equ=20;
int tmp;
while(scanf("%d",&tmp)==1)
{
memset(a,0,sizeof(a));
a[0][var]=tmp;
for(int i=1;i<equ;i++) scanf("%d",&a[i][var]);
//debug();
for(int i=0;i<var;i++)
{
if(i!=0) a[i-1][i]=1;
if(i!=var-1) a[i+1][i]=1;
a[i][i]=1;
}
//debug();
printf("%d\n",gauss());
}
return 0;
}
这个题目比前两个就难很多了,不同的是方程的数量 != 变量的数量 ,而且也不是对2 取模了,而是对7取模……要用到扩展欧几里得
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=300;
int a[maxn][maxn+1],x[maxn];
int equ,var,free_num;
void Debug()
{
for(int i=0;i<equ;i++)
{
for(int j=0;j<var+1;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}
int gcd(int a,int b)
{
if(a<0) return gcd(-a,b);
if(b<0) return gcd(a,-b);
return b==0?a:gcd(b,a%b);
}
int change(char *s){
if(strcmp(s,"MON")==0)
return 1;
else if(strcmp(s,"TUE")==0)
return 2;
else if(strcmp(s,"WED")==0)
return 3;
else if(strcmp(s,"THU")==0)
return 4;
else if(strcmp(s,"FRI")==0)
return 5;
else if(strcmp(s,"SAT")==0)
return 6;
else return 7;
}
int ex_gcd(int a,int b,int &x,int &y)
{
if(b==0){
x=1,y=0;
return a;
}
int ret=ex_gcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-a/b*y;
return ret;
}
void gauss()
{
int k,col=0;
for(k=0;k<equ&&col<var;k++,col++)
{
int mx=k;
for(int i=k+1;i<equ;i++)
if(a[i][col]>a[mx][col]) mx=i;
if(mx!=k)
for(int i=k;i<var+1;i++) swap(a[k][i],a[mx][i]);
if(!a[k][col]) { k--;continue; }
for(int i=k+1;i<equ;i++)
if(a[i][col]!=0)
{
int lcm=a[k][col]/gcd(a[k][col],a[i][col])*a[i][col];
int ta=lcm/a[i][col],tb=lcm/a[k][col];
if(a[i][col]*a[k][col] < 0) tb = -tb;
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta)%7 - (a[k][j]*tb)%7+7)%7;
}
}
for(int i=k;i<equ;i++)
if(a[i][col]!=0) {
puts("Inconsistent data.");
return;
}
if(k<var){
printf("Multiple solutions.\n");
return;
}
for(int i=0,j;i<equ;i++)
if(a[i][i]==0){
for(j=i+1;j<var;j++)
if(a[i][j]) break;
if(j>=var) break;
for(int r=0;r<equ;r++) swap(a[r][i],a[r][j]);
}
for(int i=k-1;i>=0;i--)
{
int tmp=a[i][var]%7,x1,y;
for(int j=i+1;j<var;j++)
if(a[i][j]) tmp=((tmp-x[j]*a[i][j])%7+7)%7;
int gcd=ex_gcd(a[i][i],7,x1,y);
x[i]=(x1*tmp/gcd%7+7)%7;
}
for(int i=0;i<var;i++)
if(x[i]<3) x[i]+=7;
printf("%d",x[0]);
for(int i=1;i<var;i++)
printf(" %d",x[i]);
puts("");
}
int main()
{
int p,d;
char s1[10],s2[10];
while(scanf("%d%d",&var,&equ),(var||equ))
{
memset(a,0,sizeof(a));
memset(x,0,sizeof(x));
for(int i=0;i<equ;i++)
{
scanf("%d%s%s",&p,s1,s2);
a[i][var]=((change(s2)-change(s1))%7+8)%7;
for(int j=0;j<p;j++){
scanf("%d",&d);
a[i][d-1]++;
a[i][d-1]%=7;
}
}
gauss();
}
return 0;
}
感觉这个题目,理解题意要比做题难…… 其实就是很裸地求模高斯消元模版题
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=70;
int mod,a[maxn][maxn+1],x[maxn],equ,var;
char s[100];
void init()
{
equ=strlen(s);
var=equ;
for(int i=0;i<var;i++)
{
int tmp=1;
for(int j=0;j<var;j++)
{
a[i][j]=tmp;
tmp=tmp*(i+1)%mod;
}
a[i][var]= (s[i]=='*')?0:(s[i]-'a'+1);
}
}
void debug()
{
for(int i=0;i<equ;i++)
{
for(int j=0;j<=var;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}
int gcd(int a,int b)
{
if(a<0) return gcd(-a,b);
if(b<0) return gcd(a,-b);
return b==0?a:gcd(b,a%b);
}
int ex_gcd(int a,int b,int &x,int &y)
{
if(b==0){
x=1,y=0;
return a;
}
int ret=ex_gcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-a/b*y;
return ret;
}
void gauss()
{
int k,col;
for(k=col=0;k<equ&&col<var;k++,col++)
{
int mx=k;
for(int i=k+1;i<equ;i++)
if(a[i][col]>a[mx][col]) mx=col;
if(k!=col){
for(int i=k;i<var+1;i++)
swap(a[k][i],a[mx][i]);
}
if(!a[k][col]){
k--;continue;
}
for(int i=k+1;i<equ;i++)
if(a[i][col])
{
int lcm=a[k][col]/gcd(a[k][col],a[i][col])*a[i][col];
int ta=lcm/a[i][col],tb=lcm/a[k][col];
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta-a[k][j]*tb)%mod+mod)%mod;
}
}
for(int i=k;i<equ;i++)
if(a[i][col]) return;
for(int i=0,j;i<equ;i++)
if(!a[i][i])
{
for(j=i+1;j<var;j++)
if(a[i][j]) break;
if(j>=var) break;
for(int r=0;r<equ;r++) swap(a[r][i],a[r][j]);
}
// debug();
for(int i=k-1;i>=0;i--)
{
int tmp=a[i][var],x1,y1;
for(int j=i+1;j<var;j++)
tmp=((tmp-a[i][j]*x[j])%mod+mod)%mod;
int gcd=ex_gcd(a[i][i],mod,x1,y1);
x[i]=(x1*tmp/gcd%mod+mod)%mod;
}
printf("%d",x[0]);
for(int i=1;i<var;i++) printf(" %d",x[i]);
puts("");
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %s",&mod,s);
init();
// debug();
gauss();
}
return 0;
}
思路: 每个开关都有动和不动两个选择,所以可以用1 来表示动 ,0表示不动
假如三个开关, 然后用一组向量来表示最终结果Li 表示第i个开关最终是否动了,即向量组 ( L1, L2, L3)
用(x1,x2,x3)来表示最终是动还是不动,那么就有
a11*x1 + a12*x2 +a13*x3 = L1 mod 2
a21*x1 + a22*x2 +a23*x3 = L2 mod 2
a31*x1 + a32*x2 +a33*x3 = L3 mod 2
如果 i 灯能是j 灯亮 ,那么a[j][i ] ==1 ,为什么其实仔细想想就明白了
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=29;
int a[maxn][maxn+1],equ,var,x[maxn],pre[maxn];
void debug()
{
for(int i=0;i<equ;i++)
{
for(int j=0;j<var+1;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}
int gcd(int a,int b)
{
if(a<0) return gcd(-a,b);
if(b<0) return gcd(a,-b);
return b==0?a:gcd(b,a%b);
}
void gauss()
{
int k,col;
for(k=col=0;k<equ&&col<var;k++,col++)
{
int mx=k;
for(int i=k+1;i<equ;i++)
if(a[i][col]>a[k][col]) mx=i;
//cout<<mx<<endl;
if(mx!=k){
for(int i=k;i<var+1;i++) swap(a[k][i],a[mx][i]);
}
if(!a[k][col]){
k--;continue;
}
for(int i=k+1;i<equ;i++)
if(a[i][col])
{
int lcm=a[i][col]/gcd(a[i][col],a[k][col])*a[k][col];
int ta=lcm/a[i][col],tb=lcm/a[k][col];
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta-a[k][j]*tb)%2+2)%2;
}
}
// debug();
// cout<<endl;
for(int i=k;i<equ;i++)
if(a[i][col]){
puts("Oh,it's impossible~!!");
return;
}
printf("%d\n",1<<(var-k));
}
int main()
{
int T,tmp,t2,t1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&equ);var=equ;
for(int i=0;i<var;i++) scanf("%d",&pre[i]);
memset(a,0,sizeof(a));
for(int i=0;i<var;i++)
{
scanf("%d",&tmp);
a[i][var]=pre[i]^tmp;
a[i][i]=1;
}
while(scanf("%d%d",&t1,&t2),(t1||t2)) a[t2-1][t1-1]=1;
gauss();
}
return 0;
}
这个题目跟上个题目类似,不过要注意的是答案可能超int,然后就是初始化举证 a 在经过一次高斯肖元后要改动,所以要存起来,然后再高斯肖元前赋值给a,在这点wa了几次,还是看了别人的题解报告才发现的,泪……
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=50;
int a[maxn][maxn+1],equ,var,x[maxn],pre[maxn],b[maxn][maxn+1];
void debug()
{
for(int i=0;i<equ;i++)
{
for(int j=0;j<var+1;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}
int abs(int a)
{
return a<0?-a:a;
}
int gcd(int a,int b)
{
if(a<0) return gcd(-a,b);
if(b<0) return gcd(a,-b);
return b==0?a:gcd(b,a%b);
}
void gauss()
{
int k,col;
for(k=col=0;k<equ&&col<var;k++,col++)
{
int mx=k;
for(int i=k+1;i<equ;i++)
if(a[i][col]>a[k][col]) mx=i;
if(mx!=k){
for(int i=k;i<var+1;i++) swap(a[k][i],a[mx][i]);
}
if(!a[k][col]){
k--;continue;
}
for(int i=k+1;i<equ;i++)
if(a[i][col])
{
int lcm=a[i][col]/gcd(a[i][col],a[k][col])*a[k][col];
int ta=lcm/a[i][col],tb=lcm/a[k][col];
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta-a[k][j]*tb)%2+2)%2;
}
}
//debug();
for(int i=k;i<equ;i++)
if(a[i][col]){
puts("0");
return;
}
printf("%I64d\n",1LL<<(var-k));
}
int main()
{
int T,tmp,t2,t1,k,ca=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&equ,&var);
memset(b,0,sizeof(b));
for(int i=0;i<var;i++)
{
scanf("%d",&k);
for(int j=0;j<k;j++)
scanf("%d",&tmp),b[tmp-1][i]=1;
}
scanf("%d",&k);
printf("Case %d:\n",ca++);
while(k--)
{
memcpy(a,b,sizeof(b));
for(int i=0;i<equ;i++) scanf("%d",&a[i][var]);
gauss();
}
}
return 0;
}
高斯肖元典型的题目,枚举自由变量
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=100;
int a[maxn][maxn+1],equ,var,x[maxn],pre[maxn];
void debug()
{
for(int i=0;i<equ;i++)
{
for(int j=0;j<var+1;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}
int abs(int a)
{
return a<0?-a:a;
}
int gcd(int a,int b)
{
if(a<0) return gcd(-a,b);
if(b<0) return gcd(a,-b);
return b==0?a:gcd(b,a%b);
}
void gauss()
{
int k,col;
for(k=col=0;k<equ&&col<var;k++,col++)
{
int mx=k;
for(int i=k+1;i<equ;i++)
if(a[i][col]>a[k][col]) mx=i;
if(mx!=k){
for(int i=k;i<var+1;i++) swap(a[k][i],a[mx][i]);
}
if(!a[k][col]){
k--;continue;
}
for(int i=k+1;i<equ;i++)
if(a[i][col])
{
int lcm=a[i][col]/gcd(a[i][col],a[k][col])*a[k][col];
int ta=lcm/a[i][col],tb=lcm/a[k][col];
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta-a[k][j]*tb)%2+2)%2;
}
}
//debug();
for(int i=k;i<equ;i++)
if(a[i][col]){
puts("impossible");
return;
}
for(int i=0,j;i<equ;i++)
if(a[i][i]==0){
for(j=i+1;j<var;j++)
if(a[i][j]) break;
if(j>=var) break;
for(int r=0;r<equ;r++) swap(a[r][i],a[r][j]);
}
memset(x,0,sizeof(x));
int Min=99999999;
for(int j=0;j<(1<<(equ-k));j++)
{
int tmp=j,p=equ-1;
while(tmp) x[p--]=tmp%2,tmp>>=1;
for(int i=k-1;i>=0;i--)
{
int tmp=a[i][var]%2;
for(int j=i+1;j<var;j++)
if(a[i][j]) tmp=(tmp-a[i][j]*x[j]%2+2)%2;
x[i]=(tmp/a[i][i])%2;
}
tmp=0;
for(int i=0;i<var;i++) tmp+=x[i];
Min=min(Min,tmp);
}
printf("%d\n",Min);
}
int main()
{
int T,tmp,t2,t1,k,ca=1,d;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&equ,&d);
var=equ;
memset(a,0,sizeof(a));
for(int i=0;i<var;i++)
scanf("%d",&a[i][var]);
for(int i=0;i<var;i++)
{
for(int j=0;j<=d;j++)
{
if(i-j>=0) a[i-j][i]=1;
if(i+j<var) a[i+j][i]=1;
}
}
// debug();
gauss();
}
return 0;
}
1022

被折叠的 条评论
为什么被折叠?



