用胜负表判断每轮结果,并用取模从双方周期序列中取当前手势。
OJ: luogu
题目 ID: P1328
难度:普及-
标签:模拟周期python
日期: 2026-07-15 21:35
题意
小 A 和小 B 各有一个周期出拳序列,一共比赛 N 轮。每轮按五种手势的胜负关系决定得分,平局不得分。输出两人的总分。
思路
先把胜负关系写成表 win[a][b]:
text
win[a][b] = 1 表示手势 a 能赢手势 b第 round_index 轮时:
python
gesture_a = pattern_a[round_index % length_a]
gesture_b = pattern_b[round_index % length_b]用取模就能循环使用周期序列。然后查表给胜者加分。
这题是周期模拟和查表练习,不创建 brute.py。
Python 知识
/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:整数数组用list(map(int, input().split()))读取。/home/rainboy/mycode/hugo-blog/content/program_language/python/collections_toolkit.md:二维列表可以作为固定规则表使用。% length是周期访问的常用写法。- 查表比写大量
if更稳定。
代码
python
win = [
[0, 0, 1, 1, 0],
[1, 0, 0, 1, 0],
[0, 1, 0, 0, 1],
[0, 0, 1, 0, 1],
[1, 1, 0, 0, 0],
]
n, length_a, length_b = map(int, input().split())
pattern_a = list(map(int, input().split()))
pattern_b = list(map(int, input().split()))
score_a = 0
score_b = 0
for round_index in range(n):
gesture_a = pattern_a[round_index % length_a]
gesture_b = pattern_b[round_index % length_b]
if win[gesture_a][gesture_b]:
score_a += 1
elif win[gesture_b][gesture_a]:
score_b += 1
print(score_a, score_b)cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
// win[a][b] = 1 表示手势 a 能赢手势 b
int win[5][5] = {
{0, 0, 1, 1, 0},
{1, 0, 0, 1, 0},
{0, 1, 0, 0, 1},
{0, 0, 1, 0, 1},
{1, 1, 0, 0, 0},
};
const int MAXLEN = 205;
int n, len_a, len_b;
int a[MAXLEN]; // A 的出拳周期
int b[MAXLEN]; // B 的出拳周期
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> len_a >> len_b;
for (int i = 0; i < len_a; i++) cin >> a[i];
for (int i = 0; i < len_b; i++) cin >> b[i];
int score_a = 0, score_b = 0;
// 模拟 n 轮
for (int i = 0; i < n; i++) {
int ga = a[i % len_a]; // 取模得到当前手势
int gb = b[i % len_b];
if (win[ga][gb]) // A 赢
score_a++;
else if (win[gb][ga]) // B 赢
score_b++;
// 平局不处理
}
cout << score_a << " " << score_b << "\n";
return 0;
}cpp
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200 + 10;
int n, na, nb, a[MAXN], b[MAXN], cnta, cntb;
// vs[x][y] = 1 表示甲出 x、乙出 y 时甲赢,0 表示甲输或平
int vs[5][5] = {{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}};
int main()
{
cin >> n >> na >> nb;
for(int i = 0; i < na; i++) cin >> a[i];
for(int i = 0; i < nb; i++) cin >> b[i];
for(int i = 0; i < n; i++)
{
// 周期循环:a[i%na] 取到第 i 轮 A 的出手
cnta += vs[a[i % na]][b[i % nb]];
cntb += vs[b[i % nb]][a[i % na]];
}
cout << cnta << " " << cntb << endl;
return 0;
}
复杂度
模拟 N 轮,每轮常数时间,时间复杂度是
总结
周期模拟题通常用下标取模;规则复杂但规模固定时,用表格表达胜负关系更清楚。
