The Water Bowls
一个由20个数字(0或1)组成的数列,问最少操作多少次能将其变成一个全0数列,每次操作可以选择一个数字,将其左边右边和本身翻转
#include<iostream> #include<cstdio> using namespace std; int a[22],b[22],ans1,ans2; int main(){ for(int i=1;i<=20;i++)scanf("%d",&a[i]),b[i]=a[i]; for(int i=2;i<=20;i++){ if(a[i-1]==1){ a[i-1]^=1; a[i]^=1; a[i+1]^=1; ans1++; } } for(int i=19;i>=1;i--){ if(b[i+1]==1){ b[i+1]^=1; b[i]^=1; b[i-1]^=1; ans2++; } } printf("%d",min(ans1,ans2)); return 0; }
#include<iostream> #include<cstdio> #include<cstring> #define INF 0x3fffffff #define maxn 20 using namespace std; int a[22][22],x[22],free_n; 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 guass(){ int k,col=0; for(k=0;k<20&&col<20;k++,col++){ int mx=k; for(int i=k+1;i<20;i++) if(a[i][col]>a[mx][col])mx=i; for(int i=k;i<21;i++)swap(a[k][i],a[mx][i]); if(!a[k][col]){k--;continue;}//不太明白为什么要k-- for(int i=k+1;i<20;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<21;j++) a[i][j]=((a[i][j]*ta)%2-(a[k][j]*tb)%2+2)%2; } } } for(int i=0,j;i<20;i++){ if(!a[i][i]){ for(j=i+1;j<20;j++) if(a[i][j])break; if(j==20)break; for(int r=0;r<20;r++)swap(a[r][i],a[r][j]); } } int mn=INF; for(int j=0;j<(1<<(20-k));j++){ for(int i=0;i<(20-k);i++) if(j&(1<<i))x[20-1-i]=1; else x[20-1-i]=0; for(int i=k-1;i>=0;i--){ int tmp=a[i][20]%2; for(int j=i+1;j<20;j++) if(a[i][j])tmp=(tmp-a[i][j]*x[j]%2+2)%2; x[i]=(tmp/a[i][i])%2; } int tmp=0; for(int i=0;i<20;i++)tmp+=x[i]; mn=min(mn,tmp); if(mn==0)break; } return mn; } int main(){ freopen("Cola.txt","r",stdin); for(int i=0;i<20;i++){//枚举对每个数字进行操作 scanf("%d",&a[i][20]); a[i][i]=1; if(i>0)a[i-1][i]=1; if(i<19)a[i+1][i]=1; } printf("%d",guass()); }