题解:P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布
ShirasuAzusaSaikou · · 题解
这是一道模拟题,我们只需要模拟过程就行。
很容易看到对于甲乙双方,平是等价的,而甲对乙赢=乙对甲输。
因此可以得出以下图表,然后再模拟周期即可。
PS:其实可以把平理解成一条线,然后另外一边是相反的镜像。
| 剪刀 | 石头 | 布 | 蜥蜴人 | 斯波克 | |
|---|---|---|---|---|---|
| 剪刀 | 平 | 输 | 赢 | 赢 | 输 |
| 石头 | 赢 | 平 | 输 | 赢 | 输 |
| 布 | 输 | 赢 | 平 | 输 | 赢 |
| 蜥蜴人 | 输 | 输 | 赢 | 平 | 赢 |
| 斯波克 | 赢 | 赢 | 输 | 输 | 平 |
#include <bits/stdc++.h>
using namespace std;
//0:剪刀
//1:石头
//2:布
//3:蜥蜴人
//4。斯波克
const static int win(int a, int b){
if(a == 0){
if(b == 0) return 0;
if(b == 1) return -1;
if(b == 2) return 1;
if(b == 3) return 1;
if(b == 4) return -1;
}
else if(a == 1){
if(b == 0) return 1;
if(b == 1) return 0;
if(b == 2) return -1;
if(b == 3) return 1;
if(b == 4) return -1;
}
else if(a == 2){
if(b == 0) return -1;
if(b == 1) return 1;
if(b == 2) return 0;
if(b == 3) return -1;
if(b == 4) return 1;
}
else if(a == 3){
if(b == 0) return -1;
if(b == 1) return -1;
if(b == 2) return 1;
if(b == 3) return 0;
if(b == 4) return 1;
}
else{
if(b == 0) return 1;
if(b == 1) return 1;
if(b == 2) return -1;
if(b == 3) return -1;
if(b == 4) return 0;
}
return 0x3F3F3F3F;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, na, nb;
cin >> n >> na >> nb;
int a[na], b[nb];
for(int i = 0; i < na; i++) cin >> a[i];
for(int i = 0; i < nb; i++) cin >> b[i];
int cnta = 0, cntb = 0, ia = 0, ib = 0;
for(int i = 1; i <= n; i++){
int flag = win(a[ia++ % na], b[ib++ % nb]); //模拟周期
if(flag == 1){
cnta++; //小A赢
}
if(flag == -1){
cntb++; //小B赢
}
}
cout << cnta << " " << cntb << endl;
return 0;
}