Clarke and chemistry
Accepts: 206
Submissions: 601
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
克拉克是一名人格分裂患者。某一天克拉克转换成了一名初中生,去考化学(实在编不下去了QAQ)。 考完后克拉克发现他没有得到满分,摔!他看了一下卷子,发现一个极其傻逼的化合反应配平他配错了(心里千万只哔~在奔腾)。 他十分不爽,于是想写一个程序来完成这个问题,于是他把问题交给了你。 克拉克遇到的化合反应是这样的: 你有两种化合物,A和B,A由∣A∣种元素组成,B由∣B∣种元素组成。 已知生成物为C,且系数为1。求出A和B的系数a,b使得化合反应aA+bB=C, a,b∈N∗成立。
输入描述
第一行是数据组数T(1≤T≤10). 每组数据第一行是三个整数A,B,C(1≤A,B,C≤26),分别表示∣A∣,∣B∣,∣C∣。 接下来A+B+C行,每行形如X c,分别表示A,B,C中元素X的个数为c(X为26个大写字母其中之一,保证同一物质中不会出现重复的元素,1≤c≤100)
输出描述
对于每组数据,输出一行。 如果能配平,输出字典序最小的答案(a最小的情况下b最小)。否则输出NO。
输入样例
2 2 3 5 A 2 B 2 C 3 D 3 E 3 A 4 B 4 C 9 D 9 E 9 2 2 2 A 4 B 4 A 3 B 3 A 9 B 9
输出样例
2 3 NO
Hint
第一组样例,取第一种物质2个第二种物质3个就能配平得到第三种物质。 第二组样例,无论怎么弄,都配不出来。
思路:
因为a,b都不大,所以直接暴力枚举a,b是否与C相同就行了。
AC代码:
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<cstdio> using namespace std; #define T 100010 typedef long long ll; int a[50],b[50],c[50]; int main() { #ifdef zsc freopen("input.txt","r",stdin); #endif int N,A,B,C; scanf("%d",&N); while(N--) { scanf("%d%d%d",&A,&B,&C); char s; int m; int i,j,k; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); for(i=0;i<A+B+C;++i){ scanf("\n%c%d",&s,&m); if(i<A){ a[s-'A'] = m; } else if(i<A+B){ b[s-'A'] = m; } else { c[s-'A'] = m; } } bool f1,f2=true; for(i=1;i<=100;++i){ for(j=1;j<=100;++j){ f1 = false; for(k=0;k<=25;++k){ if(a[k]*i+b[k]*j!=c[k]){ f1 = true; break; } } if(!f1){ f2 = false; break; } } if(!f2)break; } if(!f2){ printf("%d %d\n",i,j); } else { printf("NO\n"); } } return 0; }