上海大学第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;
}
	
		
posted @ 2023-04-18 08:57  春始于雪之下  阅读(27)  评论(0编辑  收藏  举报