题目大意:
至多有12个硬币,编号A-L,里面有一枚假币。多组数据,每组给出三次称量结果(even,up,down),保证可以找到假币,要求你输出假币编号并指出假币是比真币轻还是比真币重。
解题思路:
起初对所有硬币标记0;如果是even,则两边所有的硬币都是真的(记10);否则就对不确定的硬币记录怀疑(++或者--);最后只要看哪个硬币的绝对值最大,也就是被怀疑的次数最多,即是假币。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/*A-L的阿斯克码为65-76*/
int val[77];
/* 处理不平衡状态 */
void work(int len, char wi[], char li[])
{
int j;
for (j = 0; j < len; j++)
{
/* 对重的一边,已经是真的不需要再判断 */
if (val[wi[j]] != 10)
{
val[wi[j]]++;
}
/* 对轻的一边,已经是真的不需要再判断 */
if (val[li[j]] != 10)
{
val[li[j]]--;
}
}
}
int main()
{
char l[3][7], r[3][7], w[3][5];
int i, j, n, len, max, maxid;
/*freopen("1.txt","r",stdin);*/
scanf("%d", &n);
while(n--)
{
/* 初始化标记数组 */
for (i = 65; i < 77; i++)
{
val[i] = 0;
}
/* 对每组三次称量进行处理 */
for (i = 0; i < 3; i++)
{
scanf("%s%s%s", l[i], r[i], w[i]);
len = strlen(l[i]);
/* 如果相等则所有硬币都是真的,置10 */
if (w[i][0] == 'e')
{
for (j = 0; j < len; j++)
{
val[l[i][j]] = 10;
val[r[i][j]] = 10;
}
}
/* 如果左边重 */
else if (w[i][0] == 'u')
{
work(len, l[i], r[i]);
}
/* 如果左边轻 */
else if (w[i][0] == 'd')
{
work(len, r[i], l[i]);
}
}
/* 找出哪个硬币被怀疑最多次 */
max = maxid = 0;
for (i = 65; i < 77; i++)
{
if (val[i] != 10 && abs(val[i]) > max)
{
max = abs(val[i]);
maxid = i;
}
}
/* 输出假币信息 */
if (val[maxid] > 0)
{
printf("%c is the counterfeit coin and it is heavy.\n", maxid);
}
else
{
printf("%c is the counterfeit coin and it is light.\n", maxid);
}
}
return 0;
}
寻找假币算法解析

266

被折叠的 条评论
为什么被折叠?



