题解 csp.ac #30. 斗地主(T1-9)

Posted poi-bolg-poi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 csp.ac #30. 斗地主(T1-9)相关的知识,希望对你有一定的参考价值。

题目

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)的主要内容,如果未能解决你的问题,请参考以下文章

跑得快人工智能自动代打训练程序设计

寒假代更新计划

棋牌平台制作教程之斗地主选牌算法

4.30-5.1cf补题

noip斗地主

luogu2540 斗地主增强版