小红和小紫的取素因子游戏
思路
经典博弈论问题。小红和小紫轮流对正整数 x 操作:每次选一个 x 的素因子 k(k > 1),把 x 变成 x/k。谁先没法操作谁就输,小红先手。
关键观察:不管怎么选素因子,总操作次数是固定的,等于 x 的素因子个数(含重复)。
为什么?每次操作都是把 x 除以它的某个素因子,也就是从 x 的质因数分解里去掉一个素因子。不管你每次选哪个素因子去掉,最终都要把所有素因子去完才会变成 1。所以总步数 = x 的质因数分解中素因子的总个数(计重数)。
比如 x = 12 = 2^2 * 3,一共 3 个素因子(两个 2 和一个 3),不管怎么操作都是 3 步。
有了这个结论就简单了:
- 总步数为奇数:先手(小红)赢,输出
kou - 总步数为偶数:后手(小紫)赢,输出
yukari - 特别地,x = 1 时步数为 0(偶数),小红直接没法操作,输出
yukari
做法就是对每个 x 做质因数分解,数一下素因子总个数,判奇偶即可。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
scanf("%d", &t);
while (t--) {
long long x;
scanf("%lld", &x);
int cnt = 0;
for (long long i = 2; i * i <= x; i++) {
while (x % i == 0) {
cnt++;
x /= i;
}
}
if (x > 1) cnt++;
puts(cnt % 2 == 1 ? "kou" : "yukari");
}
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
StringBuilder sb = new StringBuilder();
while (t-- > 0) {
long x = sc.nextLong();
int cnt = 0;
for (long i = 2; i * i <= x; i++) {
while (x % i == 0) {
cnt++;
x /= i;
}
}
if (x > 1) cnt++;
sb.append(cnt % 2 == 1 ? "kou" : "yukari").append('\n');
}
System.out.print(sb);
}
}
import sys
input = sys.stdin.readline
def solve():
t = int(input())
out = []
for _ in range(t):
x = int(input())
cnt = 0
i = 2
while i * i <= x:
while x % i == 0:
cnt += 1
x //= i
i += 1
if x > 1:
cnt += 1
out.append("kou" if cnt % 2 == 1 else "yukari")
print('\n'.join(out))
solve()
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
const lines = [];
rl.on('line', line => lines.push(line));
rl.on('close', () => {
let idx = 0;
const t = parseInt(lines[idx++]);
const out = [];
for (let i = 0; i < t; i++) {
let x = BigInt(lines[idx++].trim());
let cnt = 0;
for (let d = 2n; d * d <= x; d++) {
while (x % d === 0n) {
cnt++;
x /= d;
}
}
if (x > 1n) cnt++;
out.push(cnt % 2 === 1 ? "kou" : "yukari");
}
console.log(out.join('\n'));
});
复杂度分析
- 时间复杂度:
,每组数据做一次试除法分解质因数。
- 空间复杂度:
,只用了常数额外空间。
小结
这题的核心洞察是:每次操作恰好消耗一个素因子,所以不管双方怎么选,总操作步数等于 x 的质因数分解中素因子的总个数(计重数),是一个定值。博弈的胜负完全由这个数的奇偶性决定。看到这类"两人轮流操作、操作次数有上界"的博弈题,第一反应就是去找不变量——总步数是否固定,固定的话判奇偶就行。



京公网安备 11010502036488号