#30. 斗地主(T1-9)
Posted zzz-hhh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#30. 斗地主(T1-9)相关的知识,希望对你有一定的参考价值。
蒟蒻又双叒叕来刷模拟了
题目描述
我们将每一张牌用两个整数表示。
第一个整数表示花色: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) 每一轮出牌中,如果双方牌型没有一方能大过另一方,则存在出千。
solution
我们先判断有没有重拍,然后比较大小
没有什么很巧的办法只能使劲敲代码..
code
/*
Auther:_Destiny
time:2020.5.2
*/
#include <bits/stdc++.h>
#include <map>
#define ll long long
#define N 100010
#define M 1010
using namespace std;
int T, z1, z2;
int k1, k2, hua, shu, flag;
int f1[60], f2[60];
map<pair<int, int>, bool> ma;
map<int, bool> zz1, zz2;
struct node {
int da, shu;
};
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;
}
void init() {//初始化数组
ma.clear(), zz1.clear(), zz2.clear(); z1 = 0, z2 = 0;
memset(f1, 0, sizeof f1);
memset(f2, 0, sizeof f2);
}
void in() {//读入的时候判断
k1 = read();
flag = 0;
for (int i = 1; i <= k1; i++) {
hua = read(), shu = read();
if (ma[make_pair(hua, shu)] == 1) flag = 1;//判断有没有重牌
else {
ma[make_pair(hua, shu)] = 1;
if (shu == 1 || shu == 2) shu += 13;
f1[i] = shu;
if (!zz1[shu]) zz1[shu] = 1, z1++;//记录一下牌的种数后边有用
}
}
k2 = read();
for (int i = 1; i <= k2; i++) {
hua = read(), shu = read();
if (ma[make_pair(hua, shu)]) flag = 1;
else {
ma[make_pair(hua, shu)] = 1;
if (shu == 1 || shu == 2) shu += 13;
f2[i] = shu;
if (!zz2[shu]) zz2[shu] = 1, z2++;
}
}
if ((k1 != 1 && k1 != 4) || (k2 != 1 && k2 != 4)) flag = 1;
//因为只有单只,三代一和炸弹,所以如果不是1和4那就直接错
}
int work() {
node x1, y1, xx, yy;
if (k1 == 1 && k2 == 1) {//判断单只的大小
x1.da = f1[1];
xx.da = f2[1];
if (x1.da < xx.da) return 2;
else if (x1.da > xx.da) return 1;
else return 0;
}
if (k1 == 1 && k2 == 4) {//判断王炸
if (z2 == 1) return 2;
else return 0;
}
if (k1 == 4 && k2 == 1) {
if (z1 == 1) return 1;//判断王炸
else return 0;
}
if (k1 == 4 && k2 == 4) {
if (z1 != 1 && z1 != 2) return 0;
if (z2 != 1 && z2 != 2) return 0;
bool b[32] = {0};
x1.da = f1[1], x1.shu = 1, b[f1[1]] = 1;
for (int i = 2; i <= k1; i++)
if (!b[f1[i]]) {
y1.da = f1[i];
y1.shu = 1;
} else {
if (f1[i] == x1.da) x1.shu++;
if (f1[i] == y1.da) y1.shu++;
}
if (x1.shu == 2 || y1.shu == 2) return 0;
memset(b, 0, sizeof b);
xx.da = f2[1], xx.shu = 1, b[f2[1]] = 1;
for (int i = 2; i <= k2; i++)
if (!b[f2[i]]) {
yy.da = f2[i];
yy.shu = 1;
} else {
if (f2[i] == xx.da) xx.shu++;
if (f2[i] == yy.da) yy.shu++;
}
if (xx.shu == 2 || yy.shu == 2) return 0;
int d1, d2;
if ((xx.shu == 4 || yy.shu == 4) && x1.shu != 4 && y1.shu != 4) return 2;
if ((x1.shu == 4 || y1.shu == 4) && xx.shu != 4 && yy.shu != 4) return 1;
if ((x1.shu == 4 || y1.shu == 4) && (xx.shu == 4 || yy.shu == 4)) {
if (x1.shu == 4) d1 = x1.da;
if (y1.shu == 4) d1 = y1.da;//如果是两只炸弹,判断炸弹的大小
if (xx.shu == 4) d2 = xx.da;
if (yy.shu == 4) d2 = yy.da;
if (d1 > d2) return 1;
else return 2;
}
if (x1.shu == 3) d1 = x1.da;//判断三代一大小
if (y1.shu == 3) d1 = y1.da;
if (xx.shu == 3) d2 = xx.da;
if (yy.shu == 3) d2 = yy.da;
if (d1 > d2) return 1;
else return 2;
}
}
int main() {
T = read();
while (T--) {
init();
in();
if (flag == 1) {
puts("0");
continue;
}
int x = work();
cout << x << "
";
}
}
垃圾题
以上是关于#30. 斗地主(T1-9)的主要内容,如果未能解决你的问题,请参考以下文章