算法定义:算是模拟题
描述
为了检测假币,银行员工用从 1 到 N 的整数对所有硬币进行编号,从而为每枚硬币分配一个唯一的整数标识符。之后,他们开始通过在左盘和右盘中放置相等数量的硬币来称量各种硬币组。硬币的标识符和称重结果都被仔细记录下来。
您要编写一个程序,帮助银行员工使用这些称重结果确定假币的标识符。
输入
'<'表示左盘中的硬币重量小于右盘中的硬币重量,
'>'表示左盘中的硬币重量大于右盘中的硬币重量,
'='表示左盘中的硬币重量等于右盘中的硬币重量。
输出
示例输入
5 3
2 1 2 3 4
<
1 1 4
=
1 2 5
=
示例输出
3
题目介绍:
对第一次看的小朋友我先讲一下这个题的意思第一行有两个数是n和k对应示例5 和 3 说明有5个硬币 3对于的是有三个公式 他们的关系可以是< = >这三个关系,并且有且仅有一个是假币其余都是真币质量相等。每个银币都有编号 1 2 3 4 5
对于输入 5 3
,表示有5枚硬币和3组称量结果。
-
第一组称量结果:
- 左盘放置硬币1和硬币2,右盘放置硬币3和硬币4。
- 结果为
<
,表示左盘的总重量小于右盘的总重量。 - 可能的解释是,假币要么是左盘的硬币1或硬币2,要么是右盘的硬币3或硬币4。
-
第二组称量结果:
- 左盘放置硬币1,右盘放置硬币4。
- 结果为
=
,表示左右盘的总重量相等。 - 因此,硬币1和硬币4都不可能是假币。
-
第三组称量结果:
- 左盘放置硬币2,右盘放置硬币5。
- 结果为
=
,表示左右盘的总重量相等。 - 因此,硬币2和硬币5都不可能是假币。
根据这些称量结果,唯一可能是假币的是硬币3,因为它在所有称量中从未被称为轻硬币或重硬币。
题目分析和讲解:
这里直接调用北理视频的讲解b站可搜
分析: 结果为等号两边一定是真硬币,结果为不等号肯定含有假硬币所以对于所有的不等式,将轻硬币放在lightCoins里,将重硬币放在heavyCoins里, 因为只有一个假硬币,且假硬币不会一会儿轻一会儿重,所以最后假硬币的出现在lightCoins或者HeavyCoins的次数一定和不等号出现的次数相等。 若恰有一个满足条件的疑似假币,则输出
好的总结一下
等于就是真币排除,不等于进行分组lightCoins和heavyCoins,并且用容器装起来然后计算次数类似哈希表(但这种方法不涉及哈希表,而是使用简单的数组进行计数)。然后先是排除真币次数
- 大体思路
-
数据结构初始化:
- 使用三个数组来记录硬币的称重情况:
lighter[i]
:记录硬币 i 被称为轻硬币的次数。heavier[i]
:记录硬币 i 被称为重硬币的次数。isTrue[i]
:记录硬币 i 是否被确定为真币,初始为true
。
- 使用三个数组来记录硬币的称重情况:
-
处理称重结果:
- 对于
<
的结果:左盘硬币轻,右盘硬币重,分别更新lighter
和heavier
数组。 - 对于
>
的结果:左盘硬币重,右盘硬币轻,同样更新lighter
和heavier
数组。 - 对于
=
的结果:左右盘硬币重量相等,这些硬币都有可能是真币,因此标记为非假币并清除其在lighter
和heavier
数组中的计数。
- 对于
-
查找唯一假币:
- 遍历每枚硬币,如果
lighter[i]
或heavier[i]
等于 0,则表示硬币 i 在所有称重结果中都未被称为轻硬币或重硬币,因此 i 可能是假币。
- 遍历每枚硬币,如果
-
输出结果:
- 输出找到的假币编号。
-
麻辣鸡的,改了十几遍终于是代码改出来了改到了凌晨3点,好了我对这个代码进行一个细节讲解首先先计算<和>的进行vector++,左边加左右边加右。最后最后!!(就这破玩意我想急毛半天)最后算等于,就是都是真币直接把计算的vector++的全部变成0.这样就只有假币没有变成0。好的最后只要进行遍历找出那个等于1的出现次数就可以了(就是那个唯一假币)。
-
-
#include <iostream> #include <vector> using namespace std; int main() { int N, K; cin >> N >> K; vector<int> lighter(N + 1, 0); // 记录每个硬币被称为轻硬币的次数 vector<int> heavier(N + 1, 0); // 记录每个硬币被称为重硬币的次数 vector<bool> isTrue(N + 1, true); // 标记每个硬币是否被确定为真币 for (int k = 0; k < K; ++k) { int P; cin >> P; vector<int> left(P), right(P); char result; for (int i = 0; i < P; ++i) { cin >> left[i]; } for (int i = 0; i < P; ++i) { cin >> right[i]; } cin >> result; if (result == '<') { for (int i = 0; i < P; ++i) { ++lighter[left[i]]; ++heavier[right[i]]; } } else if (result == '>') { for (int i = 0; i < P; ++i) { ++lighter[right[i]]; ++heavier[left[i]]; } } else if (result == '=') { // 先确定是真币的硬币,并清除它们的计数 for (int i = 0; i < P; ++i) { if (isTrue[left[i]]) { lighter[left[i]] = 0; heavier[left[i]] = 0; } if (isTrue[right[i]]) { lighter[right[i]] = 0; heavier[right[i]] = 0; } isTrue[left[i]] = false; // 标记为非假币 isTrue[right[i]] = false; // 标记为非假币 } } } int fakeCoin = 0; for (int i = 1; i <= N; ++i) { if (lighter[i] == 0 || heavier[i] == 0) { fakeCoin = i; break; } } cout << fakeCoin << endl; return 0; }
-
感谢观看 ,摸摸几╰( ̄ω ̄o)
-