题解 csp.ac #30. 斗地主(T1-9)
Posted poi-bolg-poi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 csp.ac #30. 斗地主(T1-9)相关的知识,希望对你有一定的参考价值。
题目
思路
模拟
分析
- 先判断是否有人出千,再比较大小,出千可能有一下几种情况。
- 判断全部的牌中出现了一样的牌
- 牌型不是单张/三带一/炸弹,如果出了不止一张牌就肯定不是单张,如果出的不止四张牌就肯定不是三带一/炸弹,如果出的是四张牌要判断不同大小的牌出现的次数来判断是不是三带一/炸弹。
- 牌型都正确且大小相同。
- 没人出千就比较大小。注意2是最大的,A是次大的。
Code
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
inline void read(int &T) {
int x=0;bool f=0;char c=getchar();
while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=!f;c=getchar();}
while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
T=f?-x:x;
}
int t,times1[15],times2[15];
int type1[53],size1[53];
int type2[53],size2[53];
bool appear1[15],appear2[15];
int compare(int x,int y) {
if(x==y) return 2;
if(x==2&&y!=2) return 1;
if(y==2&&x!=2) return 0;
if(x==1&&y==2) return 0;
if(x==1&&y!=2) return 1;
if(y==1&&x==2) return 1;
if(y==1&&x!=2) return 0;
if(x>y) return 1;
if(x<y) return 0;
}
int main() {
read(t);
while(t--) {
int k1,k2;bool flag=1;
read(k1);int stop=k1*2;
for(int i=1;i<=stop;++i) {
if(i&1) read(type1[i/2+1]);
else read(size1[i/2]);
}
read(k2);stop=k2*2;
for(int i=1;i<=stop;++i) {
if(i&1) read(type2[i/2+1]);
else read(size2[i/2]);
}
if((k1!=1&&k1!=4)||(k2!=4&&k2!=1)) {
puts("0");continue;
}
for(int i=1;i<=k1;++i) {
for(int j=1;j<=k1;++j) {
if(i==j) continue;
if(type1[i]==type1[j]&&size1[i]==size1[j]) {
flag=0;break;
}
}
if(!flag) break;
}
if(!flag) {puts("0");continue;}
for(int i=1;i<=k2;++i) {
for(int j=1;j<=k2;++j) {
if(i==j) continue;
if(type2[i]==type2[j]&&size2[i]==size2[j]) {
flag=0;break;
}
}
if(!flag) break;
}
if(!flag) {puts("0");continue;}
for(int i=1;i<=k1;++i) {
for(int j=1;j<=k2;++j) {
if(type1[i]==type2[j]&&size1[i]==size2[j]) {
flag=0;break;
}
}
if(!flag) break;
}
if(!flag) {puts("0");continue;}
bool type11=0,type12=0;
bool type21=0,type22=0;
int cnt1=0,num1[5],basis1,basis2;
memset(times1,0,sizeof times1);
memset(appear1,0,sizeof appear1);
if(k1==4) {
for(int i=1;i<=k1;++i) {
++times1[size1[i]];
if(!appear1[size1[i]]) {
appear1[size1[i]]=1;
num1[++cnt1]=size1[i];
}
}
if(cnt1>2) {puts("0");continue;}
bool time3=0,time1=0,time4=0;
for(int i=1;i<=cnt1;++i) {
if(times1[num1[i]]==4) time4=1;
if(times1[num1[i]]==3) time3=1;
if(times1[num1[i]]==1) time1=1;
}
if(!time1&&!time3&&!time4) {
puts("0");continue;
}
if(time1&&time3) {
type11=1;
for(int i=1;i<=cnt1;++i) {
if(times1[num1[i]]==3) basis1=num1[i];
}
}
if(time4) {
type12=1;
basis1=num1[cnt1];
}
}
if(k1==1) basis1=size1[k1];
int cnt2=0,num2[5];
memset(times2,0,sizeof times2);
memset(appear2,0,sizeof appear2);
if(k2==4) {
for(int i=1;i<=k2;++i) {
++times2[size2[i]];
if(!appear2[size2[i]]) {
appear2[size2[i]]=1;
num2[++cnt2]=size2[i];
}
}
if(cnt2>2) {puts("0");continue;}
bool time3=0,time1=0,time4=0;
for(int i=1;i<=cnt2;++i) {
if(times2[num2[i]]==4) time4=1;
if(times2[num2[i]]==3) time3=1;
if(times2[num2[i]]==1) time1=1;
}
if(!time1&&!time3&&!time4) {
puts("0");continue;
}
if(time1&&time3) {
type21=1;
for(int i=1;i<=cnt2;++i) {
if(times2[num2[i]]==3) basis2=num2[i];
}
}
if(time4) {
type22=1;
basis2=num2[cnt2];
}
}
if(k2==1) basis2=size2[k2];
if(type22==1&&type12!=1) {
puts("2");continue;
}
if(type12==1&&type22!=1) {
puts("1");continue;
}
if((type22==1&&type12==1)||(type11==1&&type21==1)) {
if(compare(basis1,basis2)==2) {
puts("0");continue;
}
if(compare(basis1,basis2)==1) {
puts("1");continue;
}
if(compare(basis1,basis2)==0) {
puts("2");continue;
}
}
if(k1==1&&k2==4&&type21==1) {
puts("0");continue;
}
if(k2==1&&k1==4&&type11==1) {
puts("0");continue;
}
if(k1==1&&k2==1) {
if(compare(basis1,basis2)==2) {
puts("0");continue;
}
if(compare(basis1,basis2)==1) {
puts("1");continue;
}
if(compare(basis1,basis2)==0) {
puts("2");continue;
}
}
}
return 0;
}
/*
题目中样例很鬼畜,lkp推出来的样例如下。
2
1 1 1
1 1 2
3 2 3 3 4 0 5
3 1 4 0 5 3 6
*/
/*
2 0
*/
以上是关于题解 csp.ac #30. 斗地主(T1-9)的主要内容,如果未能解决你的问题,请参考以下文章