题干:
林克有12枚银币。其中有11枚真币和1枚假币。假币看起来和真币没有区别,但是重量不同。但林克不知道假币比真币轻还是重。
于是他向他朋友约珥借了一架天平,用这架天平称了这些币三次。
如果用天平称两枚硬币,发现天平平衡,说明两枚都是真的。如果用一枚真币与另一枚银币比较,发现它比真币轻或重,说明它是假币。
经过精心的设计,聪明的林克根据这三次称量结果找出假币,并且能够确定假币是轻是重。
如果给你林克的称量数据,你也可以找出假币并且确定假币是轻是重吗?(林克提供的称量数据保证一定能找出假币)。
输入:
第一行有一个数字n,表示有n组测试用例。
对于每组测试用例:
输入有三行,每行表示一次称量的结果。林克事先将银币标号为A-L。
每次称量的结果用三个以空格隔开的字符串表示:
天平左边放置的硬币 天平右边放置的硬币 平衡状态。
其中平衡状态用up, down, 或 even表示, 分别为右端高、右端低和平衡。天平左右的硬币数总是相等的。
输出:
输出哪一个标号的银币是假币,并说明它比真币轻还是重(heavy or light)。
输入样例:
1
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even
输出样例:
K is the counterfeit coin and it is light.
第一次代码:
扫描二维码关注公众号,回复:
12972533 查看本文章
#include <stdio.h>
#include <string.h>
struct
{
char name;
int flag;
}coin[12] = {
{
'A', 0}, {
'B', 0}, {
'C', 0}, {
'D', 0}, {
'E', 0}, {
'F', 0}, {
'G', 0}, {
'H', 0}, {
'I', 0}, {
'J', 0}, {
'K', 0}, {
'L', 0}};//运用结构体将 硬币名 与其 是否被称量过 相捆绑。
int main()
{
char str1[6], str2[6], str3[6], str4[6], str5[6], str6[6], result1[5], result2[5], result3[5], r;//将每次的输入都单独存储起来
int n, i, j;
scanf("%d", &n);
while (n --)
{
scanf("%s%s%s", str1, str2, result1);
for (i = 0; i < strlen(str1); i ++)
{
for (j = 0; j < 12; j ++)
{
if (coin[j].name == str1[i] || coin[j].name == str2[i])
coin[j].flag = 2;//将被称量过的硬币标记一下(flag改为2)
}
}
if (strcmp(result1, "even") == 0)//如果天平平衡,表示天平两侧均为真,将两侧硬币标记一下(flag改为1)
{
for (i = 0; i < strlen(str1); i ++)
{
for (j = 0; j < 12; j ++)
{
if (coin[j].name == str1[i] || coin[j].name == str2[i])
coin[j].flag = 1;
}
}
}
scanf("%s%s%s", str3, str4, result2);
for (i = 0; i < strlen(str3); i ++)
{
for (j = 0; j < 12; j ++)
{
if (coin[j].name == str3[i] || coin[j].name == str4[i])
coin[j].flag = 2;
}
}
if (strcmp(result2, "even") == 0)
{
for (i = 0; i < strlen(str3); i ++)
{
for (j = 0; j < 12; j ++)
{
if (coin[j].name == str3[i] || coin[j].name == str4[i])
coin[j].flag = 1;
}
}
}
scanf("%s%s%s", str5, str6, result3);
for (i = 0; i < strlen(str5); i ++)
{
for (j = 0; j < 12; j ++)
{
if (coin[j].name == str5[i] || coin[j].name == str6[i])
coin[j].flag = 2;
}
}
if (strcmp(result3, "even") == 0)
{
for (i = 0; i < strlen(str5); i ++)
{
for (j = 0; j < 12; j ++)
{
if (coin[j].name == str5[i] || coin[j].name == str6[i])
coin[j].flag = 1;
}
}
}
//上述操作将硬币分为:未被称量的(flag为0)、真币(flag为1)、假币(flag为2)
for (i = 0; i < 12; i ++)
{
if (coin[i].flag == 2)//flag为2即为假币
r = coin[i].name;
}
//结合天平状态与假币位置,分情况给出结论
if (strcmp(result1, "up") == 0)
{
for (i = 0; i < strlen(str1); i ++)
{
if (str1[i] == r)//判断假币在哪一侧
{
printf("%c is the counterfeit coin and it is heavy.", r);
break;
}
if (str2[i] == r)
{
printf("%c is the counterfeit coin and it is light.", r);
break;
}
}
}
else if (strcmp(result1, "down") == 0)
{
for (i = 0; i < strlen(str1); i ++)
{
if (str1[i] == r)
{
printf("%c is the counterfeit coin and it is light.", r);
break;
}
if (str2[i] == r)
{
printf("%c is the counterfeit coin and it is heavy.", r);
break;
}
}
}
if (strcmp(result2, "up") == 0)
{
for (i = 0; i < strlen(str3); i ++)
{
if (str3[i] == r)
{
printf("%c is the counterfeit coin and it is heavy.", r);
break;
}
if (str4[i] == r)
{
printf("%c is the counterfeit coin and it is light.", r);
break;
}
}
}
else if (strcmp(result2, "down") == 0)
{
for (i = 0; i < strlen(str3); i ++)
{
if (str3[i] == r)
{
printf("%c is the counterfeit coin and it is light.", r);
break;
}
if (str4[i] == r)
{
printf("%c is the counterfeit coin and it is heavy.", r);
break;
}
}
}
if (strcmp(result3, "up") == 0)
{
for (i = 0; i < strlen(str5); i ++)
{
if (str5[i] == r)
{
printf("%c is the counterfeit coin and it is heavy.", r);
break;
}
if (str6[i] == r)
{
printf("%c is the counterfeit coin and it is light.", r);
break;
}
}
}
else if (strcmp(result3, "down") == 0)
{
for (i = 0; i < strlen(str5); i ++)
{
if (str5[i] == r)
{
printf("%c is the counterfeit coin and it is light.", r);
break;
}
if (str6[i] == r)
{
printf("%c is the counterfeit coin and it is heavy.", r);
break;
}
}
}
}
return 0;
}
第一次总结:
- 要善于利用结构体,将变量的相关属性捆绑在一起
- 理清问题中变量可能存在的状态(如本题中有未称量、真币、假币 三种状态)
- 善于用不同数字来表示各种状态(赋值)