ZOJ 3472 Play Bridge

模拟题。

几个需要注意的地方:

1、第一轮出牌的是叫牌的下家

2、每轮赢的人下轮第一个出牌

3、每轮和判断谁赢,如果有主牌的话,主牌大的赢,否则就是和先出的那张牌同花色之间比较大的赢(其他不同花色的牌为垫牌,垫牌输)。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

struct node{
	int card[14];
	bool flag[14];
}p[4];

int dooo(int a)
{
	if(a==1)
		return 13;
	return a-1;
}

bool cmp(int a,int b)
{
	return b < a;
}

int change(int a,char sh)
{
	if(a>=1&&a<=13&&sh=='C')
		return a + 100;	
	if(a>=14&&a<=26&&sh=='D')
		return a + 100;	
	if(a>=27&&a<=39&&sh=='H')
		return a + 100;	
	if(a>=40&&a<=52&&sh=='S')
		return a + 100;
	return a;
}

int find(int put,int i,int j,char sh)
{
	int k;
	for(k=0;k<13;k++)
	{
		if(put>=1&&put<=13&&p[j].card[k]>=1&&p[j].card[k]<=13 && !p[j].flag[k])
		{
			p[j].flag[k] = true;
			return p[j].card[k];
		}
		if(put>=14&&put<=26&&p[j].card[k]>=14&&p[j].card[k]<=26 && !p[j].flag[k])
		{
			p[j].flag[k] = true;
			return p[j].card[k];
		}
		if(put>=27&&put<=39&&p[j].card[k]>=27&&p[j].card[k]<=39 && !p[j].flag[k])
		{
			p[j].flag[k] = true;
			return p[j].card[k];
		}
		if(put>=40&&put<=52&&p[j].card[k]>=40&&p[j].card[k]<=52 && !p[j].flag[k])
		{
			p[j].flag[k] = true;
			return p[j].card[k];
		}
	}
	for(k=0;k<13;k++)
	{
		if(!p[j].flag[k])
		{
			p[j].flag[k] = true;
			p[j].card[k] = change(p[j].card[k],sh);
			if(p[j].card[k] > 100)
				return p[j].card[k];
			return -100;
		}
	}
	return 0;
}

int main()
{
	int t,cnt,bid,n,i,j,fi,num,dir;
	char ch[10],sh;
	scanf("%d",&t);
	while(t--)
	{
		scanf(" %s %d %c",ch,&bid,&sh);
		memset(p,0,sizeof(p));
		for(i=0;i<4;i++)
		{
			fi = 0;
			scanf("%d",&n);
			for(j=0;j<n;j++)
			{
				scanf("%d",&num);
				p[i].card[fi++] = dooo(num) + 39; 
			}
			scanf("%d",&n);
			for(j=0;j<n;j++)
			{
				scanf("%d",&num);
				p[i].card[fi++] = dooo(num) + 26; 
			}
			scanf("%d",&n);
			for(j=0;j<n;j++)
			{
				scanf("%d",&num);
				p[i].card[fi++] = dooo(num) + 13; 
			}
			scanf("%d",&n);
			for(j=0;j<n;j++)
			{
				scanf("%d",&num);
				p[i].card[fi++] = dooo(num); 
			}
			sort(p[i].card,p[i].card+13,cmp);
//			for(int o=0;o<13;o++)
//				printf("%d ",p[i].card[o]);
//			printf("--------\n");
		}
		cnt = 0;
		dir = 0;
		if(ch[0]=='N')
			dir = 1;
		if(ch[0]=='E')
			dir = 2;
		if(ch[0]=='S')
			dir = 3;
		for(i=0;i<13;i++)
		{
			int a,b,c,d,put;

			for(int yy=0;yy<13;yy++)
			{
				if(!p[dir].flag[yy])
				{
					put = p[dir].card[yy];
					break;
				}
			}

			a = find(put,i,0,sh);
			b = find(put,i,1,sh);
			c = find(put,i,2,sh);
			d = find(put,i,3,sh);

				if(a>b&&a>c&&a>d)
					dir = 0;
				if(b>a&&b>c&&b>d)
					dir = 1;
				if(c>a&&c>b&&c>d)
					dir = 2;
				if(d>a&&d>b&&d>c)
					dir = 3;
			if(a>b&&a>d&&a>c)
			{
				cnt++;
			}
			if(c>a&&c>b&&c>d)
			{
				cnt++;
			}
		}
		if(ch[0]=='N'||ch[0]=='S')
		{
			if(cnt<bid+6)
				printf("%d\n",cnt-bid-6);
			else if(cnt>bid+6)
				printf("+%d\n",cnt-bid-6);
			else
				printf("MAKE\n");
		}
		else
		{
			cnt = 13 - cnt;
			if(cnt<bid+6)
				printf("%d\n",cnt-bid-6);
			else if(cnt>bid+6)
				printf("+%d\n",cnt-bid-6);
			else
				printf("MAKE\n");
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值