给出9个钟表的状态,给出九种操作,问最少要操作几次能把所有的钟表调回12点。
思路:
对于9个钟表分别列方程,然后高斯消元即可。
然后用每个未知量表示是否进行此操作。所以取值是1或者0
接下来就是枚举每个未知量得系数使得每个等式都成立。
等式的右边为还需要操作的次数。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define LL long long
#define bug puts("************")
using namespace std;
const int N=110;
int mat[N][N];
char s[10][10]={"ABDE","ABC","BCEF","ADG","BDEFH","CFI","DEGH","GHI","EFHI"};
int a[10];
inline int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
inline int lcm(int a,int b){
return a/gcd(a,b)*b;
}
int inv(int a,int m){
if(a==1) return 1;
return inv(m%a,m)*(m-m/a)%m;
}
void guess(int n,int m){
int i=0,j=0,r;
while(i<n&&j<m){
int r=i;
for(int k=i;k<n;k++){
if(mat[k][j]){ ///不可以用abs(mat[k][j])>abs(mat[r][j]) 不知道为啥
r=k;break;
}
}
if(mat[r][j]==0){
j++;
continue;
}
if(r!=i){
for(int k=0;k<=m;k++)swap(mat[r][k],mat[i][k]);
}
for(int k=i+1;k<n;k++){
if(mat[k][j]){
int LCM=lcm(mat[k][j],mat[i][j]);
int y=LCM/mat[k][j];
int x=LCM/mat[i][j];
for(int g=0;g<=m;g++){
mat[k][g]=mat[k][g]*y-mat[i][g]*x;
mat[k][g]=(mat[k][g]%4+4)%4;
}
}
}
i++;
j++;
}
//bug;
// for(int i=0;i<n;i++){
// for(int j=0;j<m;j++){
// cout<<mat[i][j]<<" ";
// }cout<<endl;
// }
int sum=0;
for(int i=n-1;i>=0;i--){ ///计算每个未知数的系数
int tmp=mat[i][m];
for(int j=i+1;j<m;j++){
if(mat[i][j]) tmp-=mat[i][j]*a[j];
}
tmp=(tmp%4+4)%4;
a[i]=(tmp*inv(mat[i][i],4))%4; ///求出a[i]的值,等同下方的等式
// for(a[i]=0;a[i]<=3;a[i]++) ///
// if((a[i]*mat[i][i]%4+4)%4==tmp)break;
// a[i]%=4;
sum+=a[i];
}
for(int i=0;i<m;i++){
while(a[i]){ ///按从小到大的顺序
printf("%d",i+1);
a[i]--;
sum--;
printf(sum>0?" ":"\n");
}
}
}
int main(){
for(int i=0;i<9;i++){
int len=strlen(s[i]);
for(int j=0;j<len;j++){
mat[s[i][j]-'A'][i]=1; ///第一维表示第几个方程,第二维表示第几个未知数,
///未知数表示取或者不取第i个操作
}
}
for(int i=0;i<9;i++){
scanf("%d",&mat[i][9]);
mat[i][9]=(4-mat[i][9])%4; ///代表还需要操作的次数
}
guess(9,9);
return 0;
}
暴力枚举法:
#include <string.h>
#include <stdio.h> ///other
int main()
{
int i,a[10],b[10],c[10];
for(i=1;i<=9;i++)
scanf("%d",&a[i]);
for(b[1]=0;b[1]<=3;b[1]++)
for(b[2]=0;b[2]<=3;b[2]++)
for(b[3]=0;b[3]<=3;b[3]++)
for(b[4]=0;b[4]<=3;b[4]++)
for(b[5]=0;b[5]<=3;b[5]++)
for(b[6]=0;b[6]<=3;b[6]++)
for(b[7]=0;b[7]<=3;b[7]++)
for(b[8]=0;b[8]<=3;b[8]++)
for(b[9]=0;b[9]<=3;b[9]++)
{
c[1]=(a[1]+b[1]+b[2]+b[4])%4;
c[2]=(a[2]+b[1]+b[2]+b[3]+b[5])%4;
c[3]=(a[3]+b[2]+b[3]+b[6])%4;
c[4]=(a[4]+b[1]+b[4]+b[5]+b[7])%4;
c[5]=(a[5]+b[1]+b[3]+b[5]+b[7]+b[9])%4;
c[6]=(a[6]+b[3]+b[5]+b[6]+b[9])%4;
c[7]=(a[7]+b[4]+b[7]+b[8])%4;
c[8]=(a[8]+b[5]+b[7]+b[8]+b[9])%4;
c[9]=(a[9]+b[6]+b[8]+b[9])%4;
if(c[1]+c[2]+c[3]+c[4]+c[5]+c[6]+c[7]+c[8]+c[9]==0)
{
for(i=0;i<b[1];i++) printf("1 ");
for(i=0;i<b[2];i++) printf("2 ");
for(i=0;i<b[3];i++) printf("3 ");
for(i=0;i<b[4];i++) printf("4 ");
for(i=0;i<b[5];i++) printf("5 ");
for(i=0;i<b[6];i++) printf("6 ");
for(i=0;i<b[7];i++) printf("7 ");
for(i=0;i<b[8];i++) printf("8 ");
for(i=0;i<b[9];i++) printf("9 ");
printf("\n");
return 0;
}
}
}