这道题有两种思路(只有一种能ac)
第一种(不能ac),如果有一个硬币既出现在上升一侧又出现在下降一侧,这个硬币绝对是真的。(参考我之前写的poj1013)但是这样会有一些真币无法确认。可能会多算假币。
第二种(能ac),记录一个币出现在上升一侧(w++)和下降一侧的次数(w–),再记录测试的次数。如果abs(w) == 次数,这个币是假币。但是这种做法有可能假币本身就没有每次都称量啊,可能会少算假币。
其实个人认为,两种思路都是错的,至于为什么第二种能ac,可能是因为测试数据。
用第一种思路wa了很多次,去参考了大佬的代码
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <stack>
#include <stdlib.h>
#include <stdio.h>
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define l(x) x<<1
#define r(x) x<<1|1
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
int w[1010], s[1010], jilu[1010];
int n, k;
int step;
int main()
{
while (cin>>n>>k)
{
step = 0;
memset(jilu, 0, sizeof(jilu));
memset(w, 0, sizeof(jilu));
for (int i = 0; i < k; i++)
{
int m;
char c;
cin>>m;
for (int j = 0; j < 2 * m; j++)
cin>>s[j];
getchar();
cin>>c;
if (c == '=')
{
for (int j = 0; j < 2 * m; j++)
jilu[s[j]] = 1;
}
else
if (c == '<')
{
step++;
for (int j = 0; j < m; j++)
if (jilu[s[j]] == 0)
w[s[j]]--;
for (int j = m; j < 2 * m; j++)
if (jilu[s[j]] == 0)
w[s[j]]++;
}
else
if (c == '>')
{
step++;
for (int j = 0; j < m; j++)
{
if (jilu[s[j]] == 0)
w[s[j]]++;
}
for (int j = m; j < 2 * m; j++)
{
if (jilu[s[j]] == 0)
w[s[j]]--;
}
}
}
int ans = 0, result = 0;
for (int i = 1; i <= n; i++)
if (jilu[i] == 0 && abs(w[i]) == step)
{
ans++;
result = i;
}
if (ans != 1)
printf("0\n");
else
printf("%d\n", result);
}
}