这是个很可爱的东西~
我们把方程式中的每个元素的个数提出来,就可以列方程了。
没错,因为方程是无数解的,所以我们把一个值设为1,然后用分数存答案,最后算最小公倍数。
所以我们用到了分数类。
然后:
#include<cstdio>
#include<iostream>
#include<cstring>
#define maxn 55
#define maxp 27
using namespace std;
int gcd(int x,int y){return x%y==0?y:gcd(y,x%y);}
int lcm(int x,int y){
if(x==0||y==0) return 0;
int p=gcd(x,y);return x*y/p;
}
struct frac{//分数类
int a,b;
frac operator = (int x){a=x,b=1;return *this;};
frac operator = (const frac x){a=x.a,b=x.b;if(a!=0) reduce();return *this;};
frac operator + (const frac x){
if(x.a==0) return (frac){a,b};
if(a==0) return (frac){x.a,x.b};
return (frac){b*x.a+a*x.b,b*x.b};
};
frac operator - (const frac x){
if(x.a==0) return (frac){a,b};
if(a==0) return (frac){-x.a,x.b};
return (frac){a*x.b-b*x.a,b*x.b};
};
frac operator * (const frac x){return (frac){a*x.a,b*x.b};};
frac operator / (const frac x){return (frac){a*x.b,b*x.a};};
bool operator < (const frac x){
if(a==0){
if(x.a>0&&x.b>0||x.a<0&&x.b<0) return true;
if(x.a>0&&x.b<0||x.a<0&&x.b>0) return false;
}
if(x.a==0){
if(a>0&&b>0||a<0&&b<0) return false;
if(a>0&&x.b<0||a<0&&b>0) return true;
}
return a*x.b<b*x.a;
};
bool operator > (const frac x){
if(a==0){
if(x.a>0&&x.b>0||x.a<0&&x.b<0) return true;
if(x.a>0&&x.b<0||x.a<0&&x.b>0) return false;
}
if(x.a==0){
if(a>0&&b>0||a<0&&b<0) return false;
if(a>0&&x.b<0||a<0&&b>0) return true;
}
return a*x.b>b*x.a;
};
bool operator == (const frac x){
if(a==0) if(x.a==0) return true;else return false;
if(x.a==0) if(a==0) return true;else return false;
return a*x.b==b*x.a;
};
bool operator != (const frac x){
if(a==0) if(x.a==0) return false;else return true;
if(x.a==0) if(a==0) return false;else return true;
return a*x.b!=b*x.a;
};
void reduce(){int x=gcd(a,b);a/=x,b/=x;}
};
frac Abs(frac x){
int p=x.a>0?x.a:-x.a,q=x.b>0?x.b:-x.b;
return (frac){p,q};
}
void Swap(frac &x,frac &y){
frac Q=x;
x=y;
y=Q;
}
int tot,p,x,len,total,num;
//tot 项数总数
//total 元素总数
//num 方程总数
frac Matr[maxn][maxn];
//Matr高斯消元矩阵
char s[maxn];
struct Moon{
char ch[1];
int tot;
}part[maxn][maxn];
//每部分每个元素的对方程的贡献
char name[maxn][2];
char ch1,ch2;
int flag[maxn][maxp][maxp];
int ans[maxn];
void read(int &x,int &i){
x=0;
for (;i<=len&&isdigit(s[i]);i++)
x=x*10+s[i]-48;--i;
}
int get(){return (ch2==0)?0:ch2-'a'+1;}
bool pd(int x,int y){
frac k,k1;
for (int i=1;i<=tot;++i)
if(Matr[y][i].a!=0){
k=Matr[x][1]/Matr[y][1];
break;
}
for (int i=2;i<=tot;++i)
if(Matr[y][i].a!=0){
k1=Matr[x][i]/Matr[y][i];
if(k1!=k) return true;
}else if(Matr[x][i].a!=0) return true;
return false;
}
bool judge(int x){
for (int i=1;i<x;++i)
if(!pd(x,i)) return true;
return false;
}
int main(){
freopen("chemistry.in","r",stdin);
freopen("chemistry.out","w",stdout);
//-------------------------------------------
//输入处理
int i,j,k,q,sum;
scanf("%s",s+1);
len=strlen(s+1);tot=p=1;
for (i=1;i<=len;++i){
if(s[i]=='+') ++tot;
if(s[i]=='=') ++tot,p=-1;
if(s[i]<='Z'&&s[i]>='A'){
ch1=s[i],ch2=0;
if(s[i+1]<='z'&&s[i+1]>='a') ch2=s[i+1],read(x,i+=2),sum=((x==0)?1:x)*p;
else if(isdigit(s[i+1])) read(x,i+=1),sum=((x==0)?1:x)*p;
else sum=p;
if(!flag[tot][ch1-'A'+1][get()]){
part[tot][++part[tot][0].tot].ch[0]=ch1;
part[tot][part[tot][0].tot].ch[1]=ch2;
flag[tot][ch1-'A'+1][get()]=part[tot][0].tot;
}
part[tot][flag[tot][ch1-'A'+1][get()]].tot+=sum;
}
if(s[i]=='('){
for (j=i+1;j<=len&&s[j]!=')';++j);
read(x,j+=1);q=x;
for (i++;i<=len&&s[i]!=')';++i){
ch1=s[i],ch2=0;
if(s[i+1]<='z'&&s[i+1]>='a') ch2=s[i+1],read(x,i+=2),sum=((x==0)?1:x)*p*q;
else if(isdigit(s[i+1])) read(x,i+=1),sum=((x==0)?1:x)*p*q;
else sum=p*q;
if(!flag[tot][ch1-'A'+1][get()]){
part[tot][++part[tot][0].tot].ch[0]=ch1;
part[tot][part[tot][0].tot].ch[1]=ch2;
flag[tot][ch1-'A'+1][get()]=part[tot][0].tot;
}
part[tot][flag[tot][ch1-'A'+1][get()]].tot+=sum;
}i=j;
}
}
//-------------------------------------------
//整理出所有元素
for (i=1;i<=tot;++i){
for (j=1;j<=part[i][0].tot;++j){
ch1=part[i][j].ch[0];
ch2=part[i][j].ch[1];
if(!flag[tot+1][ch1-'A'+1][get()]){
name[++total][0]=part[i][j].ch[0];
name[total][1]=part[i][j].ch[1];
flag[tot+1][ch1-'A'+1][get()]=part[i][0].tot;
}
}
}
//-------------------------------------------
//处理高斯消元矩阵
for (i=1;i<=total;++i){
++num;
ch1=name[i][0],ch2=name[i][1];
for (j=1;j<=tot;++j)
if(flag[j][ch1-'A'+1][get()]) Matr[num][j]=part[j][flag[j][ch1-'A'+1][get()]].tot;
if(flag[tot][ch1-'A'+1][get()]) Matr[num][tot]=-part[tot][flag[tot][ch1-'A'+1][get()]].tot;
if(judge(num)) --num;
}
if(num==tot) --num;
//-------------------------------------------
//高斯消元
frac P;int r;
for (i=1;i<num;++i){
r=i;
for (j=i+1;j<=num;++j)
if(Abs(Matr[r][i])<Abs(Matr[j][i])) r=j;
if(Abs(Matr[r][i])==(frac){0,1}){
printf("No Solution\n");
return 0;
}
if(r!=i)
for (j=i;j<=tot;++j)
Swap(Matr[r][j],Matr[i][j]);
for (j=i+1;j<=num;++j){
if(Matr[j][i].a){
P=Matr[i][i]/Matr[j][i];
for (k=i;k<=tot;++k){
Matr[j][k]=P*Matr[j][k];
Matr[j][k]=Matr[j][k]-Matr[i][k];
}
}
}
}
for (i=num;i>=1;--i){
for (j=i+1;j<=num;++j){
P=Matr[j][tot]*Matr[i][j];
Matr[i][tot]=Matr[i][tot]-P;
}
Matr[i][tot]=Matr[i][tot]/Matr[i][i];
}
//-------------------------------------------
//把分母都统一成1
int Lcm=1;
for (i=1;i<=num;++i){
if(Matr[i][tot].a)Matr[i][tot].reduce();
Lcm=lcm(Lcm,Matr[i][tot].b);
}
for (i=1;i<=num;++i)
ans[i]=Matr[i][tot].a*Lcm/Matr[i][tot].b;
ans[tot]=Lcm;
//-------------------------------------------
//输出
int inde=1;
if(ans[1]>1)printf("%d",ans[1]);
for (i=1;i<=len;++i){
printf("%c",s[i]);
if(s[i]=='+'||s[i]=='=')
if(ans[++inde]>1) printf("%d",ans[inde]);
}
}