CSP.ac#30斗地主

题目

小 L 喜欢斗地主,但是总是赢不了,比如对手 17 张牌秒他。在一段时间的观察之后, 他发现他的对手总是出千。于是小 L 请你编一个程序来帮他解决这个问题。

现在,小 L 开始分析自己的若干次牌局。每一次给出他和对手的一次出牌,请你判断

这一轮出牌是否有不对劲的地方,如果没有,那么谁能大过谁。

我们将每一张牌用两个整数表示。

第一个整数表示花色:0=?,1=?,2=?,3=?

第二个整数表示数字:A10=110,J, Q, K = 11, 12, 13

数字从小到大排列为:34567890JQKA2

两张牌是相同的,当且仅当他们花色和数字都相同。

出于简化,我们只考虑以下 4 种牌型,其余情况不构成合法牌型:

(1) 单张:顾名思义,单张就是一张牌。双方牌型都是单牌时,单张 X 大过单张

Y 当且仅当 X 的数字严格大过 Y 的数字。

(2) 三带一:顾名思义,三带一就是三张数字相同的牌带一张数字不同的牌。三带

一 XXXU 大过三带一 YYYV 当且仅当 X 的数字大过 Y 的数字。

(3) 炸弹:顾名思义,炸弹就是四张数字相同的牌。任意炸弹大过上面两种牌型。

炸弹 XXXX 大过炸弹 YYYY 当且仅当 X 的数字大过 Y 的数字。

其余情况不能比大小。 出于简化,我们只考虑以下 3 种出千:

(1) 每一轮出牌中,如果双方的牌中,存在完全相同的两张牌(无论是否为同一人

持有),则存在出千。

(2) 每一轮出牌中,如果一方的出牌不能构成合法牌型,则存在出千。

(3) 每一轮出牌中,如果双方牌型没有一方能大过另一方,则存在出千。

【输入格式】

第一行输入一个正整数 T,表示接下来要分析 T 轮牌局。

接下来每 2 行描述一轮牌局。每行分别描述一方的出牌。

每行第一个数 K,表示这一方出了 K 张牌。接下来 2K 个整数,表示 K 张牌花色和数 字。

【输出格式】

输出 T 行,对于每轮牌局,输出一个整数 0 表示存在出千,1 表示第一个牌型更大,2 表示第二个牌型更大。

【输入样例】

2
1 1 1
1 1 2
3 2 3 3 4 0 5
3 1 4 0 5 3 6

【输出样例】

2
0

【样例解释】

第一轮牌局,?A 对?2,后者更大。 第二轮牌局,?5 出现了 2 次,且双方都不是合法牌型,出千

就是一个大模拟,没别的了

Code

#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>

#define int long long
#define rr register

#define MAXN 10010
#define MAXM 110
#define inf 1e18

using namespace std;

const int mod = 1e9 + 7;

inline int read() {
	int s = 0, f = 0;
	char ch = getchar();
	while (!isdigit(ch)) {f |= ch == ‘-‘; ch = getchar();}
	while (isdigit(ch)) {s = s * 10 + (ch ^ 48); ch = getchar();}
	return f ? -s : s;
}

int T, n1, n2;

int q[MAXM], p[MAXM];

int a[MAXM][MAXM], b[MAXM][MAXM];

inline int chen(int x) {return (x - 3 + 14) % 14;}

inline int check() {
	int x1 = 0, x2 = 0, x3 = 0, x4 = 0, d1 = 0, d2 = 0;
	for (rr int i = 1; i <= 13; i++) {
		if (q[i] == 4)
			d1 = i;
		else if (q[i] == 3) x1 = i;
		else if (q[i] == 1) x2 = i;
	}
	for (rr int i = 1; i <= 13; i++) {
		if (p[i] == 4)
			d2 = i;
		else if (p[i] == 3) x3 = i;
		else if (p[i] == 1)  x4 = i;
	}
	// cout << 1;
	if (n1 == 4) {
		if (!d1 && ((!x1) || (!x2)))
		return 0;
	}
	if (n2 == 4) {
		if (!d2 && ((!x3) || (!x4)))
		return 0;
	}
	if (d1 && d2 && n1 == 4 && n2 == 4) {
		if (chen(d1) > chen(d2)) return 1;
		else if (chen(d1) < chen(d2)) return 2;
		else return 0;
	}
	if (d1 && !d2 && n1 == 4) return 1;
	if (!d1 && d2 && n2 == 4) return 2;
	if (x1 && x3 && n1 == 4 && n2 == 4) {
		if (chen(x1) > chen(x3)) return 1;
		else if (chen(x1) < chen(x3)) return 2;
		else return 0;
	}
	if (x1 && !x3 && n1 == 4) return 0;
	if (!x1 && x3 && n2 == 4) return 0;
	if (x2 && x4 && n1 == 1 && n2 == 1) {
		// cout << chen(x2) << chen(x4);
		if (chen(x2) > chen(x4)) return 1;
		else if (chen(x2) < chen(x4)) return 2;
		else return 0;
	}
	return 0;
}

signed main() {
	T = read();
	while (T--) {
		memset(a, 0, sizeof a);
		memset(q, 0, sizeof q);
		memset(p, 0, sizeof p);
		memset(b, 0, sizeof b);
		n1 = read();
		bool f = 0;
		for (rr int i = 1 ; i <= n1; i++) {
			int x = read();
			int y = read();
			if (a[x][y]) f = 1;
			a[x][y] = 1;
			q[y]++;
		}
		n2 = read();
		for (rr int i = 1 ; i <= n2; i++) {
			int x = read();
			int y = read();
			if (a[x][y] || b[x][y]) f = 1;
			b[x][y] = 1;
			p[y]++;
		}
		if (f) {
			cout << 0 << "\n";
			continue;
		}
		if (n1 > 4 || n2 > 4 || n1 == 2 || n1 == 3 || n2 == 2 || n2 == 3 || (n1 != n2 && n1 != 4 && n2 != 4)) {
			cout << 0 << "\n";
			continue;
		}
		cout << check() << "\n";
	}
}

自造数据

/*
2
4 1 2 2 2 3 2 0 2
1 1 4
4 1 2 2 2 3 2 0 1
1 1 3
*/
/*
1 0
*/
/*
2
4 1 2 2 2 3 2 0 1
4 0 2 1 1 2 1 3 1
4 1 2 2 2 3 2 0 2
4 0 1 1 1 2 3 3 3
*/
/*
1 0
*/
/*
2
4 1 2 2 3 3 4 0 1
4 5 6 7 8 8 9 10 11
4 1 2 2 2 3 2 0 2
4 0 1 1 1 2 3 3 3
*/

CSP.ac#30斗地主

上一篇:windows部署服务(wds),网咯引导安装windows


下一篇:win32: 制作带ALPHA通道的bmp,添加到静态文本控件上,达到背景透明效果