tags
模拟
博弈
数学
中文题面翻译
维斯特洛有 n 座城市。第 i 座城市居住着 ai 个人。丹妮莉丝(Daenerys)和史坦尼斯(Stannis)在下一盘棋:一方选择某座城池,一举将其夷为平地。这样,所有居民都会不幸身亡。史坦尼斯先开始。当维斯特洛只剩下 k 座城市时,游戏结束。
预言中说,如果存活居民的总数是双数,那么丹妮莉丝获胜:史坦尼斯被斩首,丹妮莉丝登上铁王座。如果幸存居民总数为奇数,则史坦尼斯获胜,一切走向完全相反。
培提尔-贝里席大人想知道他应该支持哪位王位候选人,因此他想知道哪位候选人有制胜的策略。回答贝里席大人的这个问题,也许您就能成为下一任赫伦霍尔领主。
输入
第一行包含两个空格分隔的正整数 n 和 k ( 1 ≤ k ≤ n ≤ 2·105 )–维斯特洛的初始城市数和游戏结束时的城市数。
第二行包含 n 个空格分隔的正整数 ai ( 1 ≤ ai ≤ 106 ),代表维斯特洛每个城市的人口数。
输出
如果丹妮莉丝获胜,则打印字符串"丹妮莉丝"(不带引号);如果史坦尼斯获胜,则打印字符串"史坦尼斯"(不带引号)。
思路
这是一个博弈
问题
简而言之,给定数组a,Daenerys的目标是让数组和为偶数,Stannis的目标是让数组和为奇数,俩人轮流操作,每次可以删除数组中一个数
由于k(k = 2,3,4,5,6,7,…)个偶数和仍为偶数,可以知道Daenerys和Stannis的争夺焦点是在奇数,因为k个奇数相加,若k=2n+1(n = 1,2,3,4,…)即k为奇数则结果为奇数,若k=2n(n = 1,2,3,4,…)即k为偶数则结果为偶数
定义奇数个数为odd
这样我们对两人的行为定义的更加明确了,Daenerys应当使得odd % 2 == 0
,而Stannis应当使得odd % 2 == 1
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n, k; cin >> n >> k;
int a, odd = 0, even = 0;
int s = 0, step_s, step_d;
// start end
for (int i = 1; i <= n; i++) {
cin >> a;
if (a & 1) odd++;
else even++;
}
if (n - k & 1) step_s = (n - k) / 2 + 1, step_d = (n - k) / 2;
else step_s = step_d = (n - k) / 2;
if (step_s >= even && (k & 1)) cout << "Stannis";
else if (step_d >= even && !(k & 1)) cout << "Daenerys";
else if (!even) {
if (k & 1) cout << "Stannis";
else cout << "Daenerys";
}
else if (!odd) cout << "Daenerys";
else if (step_d >= odd) cout << "Daenerys";
else {
bool state = 1; // S
while (n > k) {
if (state) {
if (odd & 1) {
if (even) even--;
else odd--;
}
else {
if (!(step_s > step_d)) {
cout << "Daenerys";
return 0;
}
else {
cout << "Stannis";
return 0;
}
}
step_s--;
}
else {
if (!(odd & 1)) {
if (even) even--;
else odd--;
}
else odd--;
step_d--;
}
n--;
state = !state;
}
if (odd & 1) cout << "Stannis";
else cout << "Daenerys";
}
return 0;
}