题解:P11133 【MX-X5-T5】「GFOI Round 1」World Ender
前言
I. 时间之初的歌曲。
II.完美地,或是空洞地。
III.创造奇迹,冲破世界。
World Ender - Beyond 11
题意
光光和对立在玩游戏。
有
你可以选择先手或后手,问你是否存在必胜策略。
思路
谁家好人教练赛前最后一次模拟压轴放交互啊?
这是一道交互题,仅支持 C++ 语言提交,且不支持 C++14(GCC 9)。
博弈论好题。
Get
按部就班即可,不过在保存的时候存一下原下标,后面有用。
Init
初始化,选择先后手,选择方式见下。
Play
考虑到每一次至少扔掉一片碎片,不可能出现循环。
手玩一下不难发现,真正决定结果的只有如下两种情况。
为什么说只有这两种情况是真正决定结果的呢?
当
同理,当 可怜的对立。
当
但是!你是玩家,你的目标是打赢电脑!
虽然我是光厨,但是如果初始序列给你就是堆数能两两配对的情况,你选光光(初始先手)显然是赢不了的。
为了胜利,你只能选对立。
哎这个出题人太坏了。
编译方式
想必不少人应该是第一次见到交互题,在这里说一下交互题怎么编译。
- DEV-C++ 新建项目。
- 左上角项目管理,添加项目,导入题目给出的交互判定程序和你的程序。
- 编译运行即可。
Code
#include<bits/stdc++.h>
#define pr pair<int,int>
#define mp make_pair
using namespace std;
const int M=2000;
int n,cnt,vis[M+10];
vector<pr> vec;
vector<int> Play() {
vector<int> ans(cnt,0);
sort(vec.begin(),vec.end());
if (cnt&1) for (int i=0;i<cnt;i++) vec[i].first=(cnt-i-1?vec[i+1-i%2].first:0);
else for (int i=0;i<cnt;i++) vec[i].first=(cnt-i-1?vec[i+i%2].first:vec[0].first);
for (int i=0;i<cnt;i++) ans[vec[i].second]=vec[i].first;
return ans;
}
void Get(vector<int> a) {
vec.clear();cnt=0;
for (auto i:a) vec.emplace_back(mp(i,cnt++));
return;
}
bool Init(int n,int op,vector<int> a) {
memset(vis,0,sizeof(vis));vec.clear();cnt=0;
for (auto i:a) vec.emplace_back(mp(i,cnt++));
for (auto i:a) vis[i]++;
for (int i=1;i<=M;i++) if(vis[i]&1) return false;
return true;
}