上海大学第21届程序设计联赛 I.I like UNO ! 模拟
我觉得大模拟就是需要多创建函数,很明显我在这方面还有很多不足。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <map>
#include <deque>
#include <vector>
typedef long long ll;
typedef std::pair<int, int> PII;
#define ls u << 1
#define rs u << 1 |1
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10, M = 2e5 + 10;
int n, m;
std::map<std::string, int> mp[4];//四个玩家的手牌
bool vis[4];//哪个玩家被跳过回合了
std::deque<std::string> dq;//双端队列存储牌组
std::vector<std::string> wc, nmsl;//按照题目要求进行插入
int now = 0, cur = 1;//now表示ABCD。0表示A以此类推, cur表示顺时针方向
int cut;// 因为可能最后一个打的是翻转操作的牌,所以直接记录一下上一个是哪个
inline bool win() { //判断是谁赢了
if (mp[cut].empty()) {
if(!cut) std::cout << "A" << '\n';
else if(cut == 1) std::cout << "B" << '\n';
else if(cut == 2) std::cout << "C" << '\n';
else if(cut == 3) std::cout << "D" << '\n';
else std::cout << "nmsl" << '\n';
return true;
}
return false;
}
bool ok;
inline void work(std::string sta) { //传入一个字符串,然后分类进行操作,感觉有点模范化那个意思了
cut = now;
mp[now][sta] --;
if(mp[now][sta] == 0) mp[now].erase(sta);
dq.push_back(sta);
if (sta[1] == '+') {
now = (now + cur + 4) % 4;
vis[now] = true;
mp[now][dq.front()] ++;
dq.pop_front();
mp[now][dq.front()] ++;
dq.pop_front();
} else if(sta[1] == 'R'){
cur = -cur;
now = (now + cur + 4) % 4;
} else if(sta[1] == 'S'){
now = (now + cur + 4) % 4;
vis[now] = true;
} else {
now = (now + cur + 4) % 4;
}
ok = true;
if(now > 3 || now < 0) std::cout << "nmsl" << '\n';
}
inline void Do() {//如果当前玩家没有打牌,则调用Do函数
std::string sta = dq.front();
dq.pop_front();
if(sta[0] == dq.back()[0] || sta[1] == dq.back()[1]) {//摸到的牌需要及时打出的情况
dq.push_back(sta);
cut = now;
if (sta[1] == '+') {
now = (now + cur + 4) % 4;
vis[now] = true;
mp[now][dq.front()] ++;
dq.pop_front();
mp[now][dq.front()] ++;
dq.pop_front();
} else if(sta[1] == 'R'){
cur = -cur;
now = (now + cur + 4) % 4;
} else if(sta[1] == 'S'){
now = (now + cur + 4) % 4;
vis[now] = true;
} else {
now = (now + cur + 4) % 4;
}
return ;
}
mp[now][sta] ++;//摸到的牌没有打出去的情况
now = (now + 4 + cur) % 4;
}
inline void solve() {
//按照题目顺序进行插入vector
wc.push_back("R");
wc.push_back("Y");
wc.push_back("B");
wc.push_back("G");
nmsl.push_back("+");
nmsl.push_back("R");
nmsl.push_back("S");
std::string str;
for (int i = 0; i <= 3; i ++) {
for (int j = 1; j <= 5; j ++) {
std::cin >> str;
mp[i][str] ++;
}
}
std::cin >> n;
for (int i = 1; i <= n; i ++) {
std::cin >> str;
dq.push_back(str);
}
int tot = 1;
while (true) {
if (vis[now]) {//如果当前玩家被跳过,执行如下操作
vis[now] = false;
now = (now + cur + 4) % 4;
continue;
}
ok = false;
std::string bom = dq.back();
std::string color = "";
color =+ bom[0];
if (bom[1] <= '9' && bom[1] >= '0') {//数字牌
int num = bom[1] - '0';
for (int i = 0; i < num; i ++) {
std::string pt = color + char(i + '0');
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
for (int i = 0; i < 4; i ++) {
std::string pt = wc[i] + bom[1];
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
for (int i = num + 1; i <= 9; i ++) {
std::string pt = color + char(i + '0');
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
for (int i = 0; i < 3; i ++) {
std::string pt = color + nmsl[i];
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
Do();
} else {
char ch = bom[1];
if (ch == '+') {
for (int i = 0; i <= 9; i ++) {
std::string pt = color + char(i + '0');
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
for (int i = 0; i < 4; i ++) {
std::string pt = wc[i] + "+";
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
for (int i = 0; i < 3; i ++) {
std::string pt = color + nmsl[i];
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
Do();
} else if (ch == 'R') {
for (int i = 0; i <= 9; i ++) {
std::string pt = color + char(i + '0');
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if (ok) continue;
std::string o = color + "+";
if (mp[now].count(o)) {
work(o);
if(win()) return ;
continue;
}
for (int i = 0; i < 4; i ++) {
std::string pt = wc[i] + "R";
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
o = color + "S";
if (mp[now].count(o)) {
work(o);
if(win()) return ;
continue;
}
Do();
} else if (ch == 'S') {
for (int i = 0; i <= 9; i ++) {
std::string pt = color + char(i + '0');
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
for (int i = 0; i < 2; i ++) {
std::string pt = color + nmsl[i];
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
for (int i = 0; i < 4; i ++) {
std::string pt = wc[i] + "S";
if (mp[now].count(pt)) {
work(pt);
if(win()) return ;
break;
}
}
if(ok) continue;
Do();
}
}
}
}
int main(void) {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int _ = 1;
//std::cin >> _;
while(_ --)
solve();
return 0;
}