Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述
"金条"银行从可靠来源获得的信息表明,在他们最后一组N枚硬币中,只有一枚硬币是假的,重量与其他硬币不同(而所有其他硬币的重量相同)。在经济危机之后,他们只有一点简单的余额可用。使用天秤,人们能够确定左天秤中物体的重量是否小于,大于或等于右天秤中物体的重量。
为了检测假币,银行员工按从1到N的整数对所有硬币进行编号,为每个硬币分配一个唯一的整数编号。之后,他们开始通过在天秤左边和右边中放置相同数量的硬币来称量各组硬币的重量。硬币的编号和比较称量次数被详细记录。
编写一个程序,该程序将帮助银行员工使用这些比较的结果确定假硬币的编号\
输入
输入文件的第一行包含两个整数 N 和 K,用空格分隔,其中 N 是硬币的数量 (2<=N<=1000),K 是比较的次数 (1<=K<=100)。比较完之后会输出比较的结果,所有数字均以空格分隔。第二行包含以下字符之一:"<"、">"或"="。它代表了比较的结果:
<"表示左盘中硬币的重量小于右盘中硬币的重量,
">"表示左盘中硬币的重量大于右盘中硬币的重量,
"="表示左盘中硬币的重量等于右盘中硬币的重量。\
输出
将假硬币的标识符输出,如果给的结果找不到则输出0。
输入样例
5 3
2 1 2 3 4
<
1 1 4
=
1 2 5
=
输出样例
3
思路分析
根据题意可知:
1)每次出现"=",那一次比较(那一行)全是真币
3)如果假币唯一则一定出现在每一次不等式中。
3)不论假币是轻还是重,它都只会一直出现在不等式小的一边(或大的一边)
基于上面几点:我们可以将=号左右出现的真币先排除,
然后统计所有不等号出现的次数,以及硬币在重的一边,轻的一边出现的次数。
因为只有一个假币,且它要么比其他的硬币都重,要么比其他硬币都轻
如果有且仅有一个硬币在重的或轻的一边出现的次数等于不等号出现的次数,那这个硬币一定是假币
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n, k;
while (cin >> n >> k)
{//输入硬币数、称重次数
int sum = 0;//不等号出现的次数
vector<int>coins(n + 1, 0);//硬币状态 1为真硬币,0为不能确定真假的硬币
vector<int>light(n + 1, 0);//记录放在轻的一堆的次数
vector<int>heavy(n + 1, 0);//记录放在重的一堆的次数
while(k--)
{
int x;
cin >> x;
int id[2*x];//存放硬币的编号
for (int i=0; i<2*x; i++)
cin >> id[i];//输入硬币编号
char cmp;
cin >> cmp;//输入比较结果,=或>、<
switch(cmp)
{
case '=':
for(int i=0; i<2*x; i++)
coins[id[i]] = 1;//比较的硬币都是真的,因为一样重
break;
case '<':
sum++;
for (int i=0; i<x; i++)
light[id[i]]++;//左边的硬币轻
for (int i=x; i<2*x; i++)
heavy[id[i]]++;//右边的硬币重
break;
case '>':
sum++;
for (int i=0; i<x; i++)
heavy[id[i]]++;//左边的硬币重
for (int i=x; i<2*x; i++)
light[id[i]]++;//右边的硬币轻
}
}
int slug=0,times= 0;//假币以及出现次数
for (int i=1; i<=n; i++)
{
if (coins[i]==0 && (light[i]==sum || heavy[i]==sum))
{
times++;
slug= i;
}//如果存在且仅存在一个硬币在不等号一个方向出现的次数等于不等式出现的次数
}
if (times==1)//那个硬币就一定是假币。
cout << slug;//输出假币编号
else
cout <<0;
}
return 0;
}
总结
加油呀,明天接着更新\