紫薯P50 例题3-4
一、题意
输入有好几组。
每组第一行一个数n,第二行开始,每行n个数,数字范围为1-9。
每组第二行为一个参照序列ans。
对于之后的每个序列行,它与ans序列相比,有A个数字位置正确,有B个数字在两个序列中都出现过但位置不对。输入(A, B)。
当有一行全为0时,该组结束;当n为0时,输入结束。
二、解析
统计每个数字在ans序列中出现的次数cnt_a[10];对于之后与之对比的序列b,统计每个数字在b序列中出现的次数cnt_b[10];统计每个数字在两个序列中位置相同的次数cnt_same[10]。
则 A 为所有数字位置正确的次数之和;B比较难想,就是每个数字在两个序列中出现次数的较小值减去位置相同的次数。(B可以用一个二分图来理解)
三、代码
#include <iostream> #include <cmath> using namespace std; const int maxn = 1000 + 5; int n, kase = 1; int main() { while(cin >> n && n) { cout << "Game " << kase ++ << ":\n"; int ans[maxn], cnt_a[10], cnt_b[10], cnt_same[10]; fill(cnt_a, cnt_a + 10, 0); for(int i = 0; i < n; i ++) { cin >> ans[i]; cnt_a[ans[i]] ++; } while(1) { fill(cnt_b, cnt_b + 10, 0); fill(cnt_same, cnt_same + 10, 0); bool ok = 0; for(int i = 0, x; i < n; i ++) { cin >> x; cnt_b[x] ++; if(x == ans[i]) cnt_same[x] ++; if(x != 0) ok = 1; } if(!ok) break; int A = 0, B = 0; for(int i = 1; i < 10; i ++) A += cnt_same[i], B += min(cnt_a[i], cnt_b[i]) - cnt_same[i]; cout << " (" << A << "," << B << ")" << endl; } } }
四、归纳
- 注意局部变量、数组的初始化
- 遇到数学题要先思考清楚,不要拿到题目就敲代码
- 计数的思想貌似经常用到,可以留意一下
慢慢来总会进步的吧