小米笔试题2答案

/*
扑克决斗
A,	B两人按下述规则打扑克(A先出):

1、每人摸13张牌,只能按1张或者1对出牌
2、如果一方出牌,另一方可以选择跟牌,跟牌牌型必须对方一样(一张跟一张,一对跟一对),并且牌的大小必须比对方大(2<3<4<...<10<J<Q<K<A)。
3、如果一方(比如A)出牌,另一方(比如B)也可以选择不跟。那么由A继续出牌,此时A可以选择出一对,或者一张。
4、先出完手上牌者胜

假设双方都足够聪明且知道对方手里有什么牌,请写程序(C++或Java),判断对于输入数据指定的牌局,谁将胜出。
输入数据:
共两行字符串,第一行表示A摸到的扑克牌,第二行表示B的。每行字符串为13位长,由字符0,1,2,3,4组成,例如1020301011042表示A、7、9、10各一张,3、K各两张,5三张,Q四张。
输出结果:
如果A必胜则输出A,反正输出B
*/

/*
输入:
	a	A的牌
	b	B的牌
规则:(参考打牌经验)
	1)各N张牌。
	2)A先出牌。
	2)出牌:保留最小的一手(一个,或一对,或三个中的一个,或四个中的两个)留作最后出(想象牌局:N=2; a=11,b=11),先出第二小的(除非就一手牌了)。
	3)跟牌:能跟则跟。跟牌尽可能小,以保留力量。
输出:
	胜者'A'或'B'。
*/

#include<iostream>
using namespace std;

const char CARDS[]="234567890JQKA";
const int N=sizeof(CARDS)/sizeof(char)-1;//N为有效字符个数,不包括结尾的空字符。

void swap(char*& a, char*&b);
bool isAllZero(const char*a);
bool chupai(bool who, int& index, int& count, char* a, char* b);
bool genpai(bool who, int& index, int& count, char* a, char* b);
char play(char* a, char* b);

int main()
{
	char head[N+1];
	for(int i=0; i<N; i++){
		head[i]='0'+i%10;
	}
	head[N]=0;

	cout<<head<<endl;

	char a[N+1],b[N+1];
	cin.getline(a,N+1);
	cin.getline(b,N+1);

	//char a[N+1]="1020301011042";
	//char b[N+1]="1020301011042";

	cout<<"--"<<head<<endl;
	cout<<"A:"<<a<<"\nB:"<<b<<endl;

	char winner=play(a,b);
	cout<<"赢家:"<<winner<<endl;

	return 0;
}


void swap(char*& a, char*& b)
{
	char *tmp=a;
	a=b;
	b=tmp;
}

bool isAllZero(const char*a)
{
	int i=0;
	for (; i<N && a[i]=='0'; i++){}//判断条件中,i<N必须放在a[i]=='0'前面,因为i<N是访问a[i]的前提。
	return  i==N;
}

/*
who		出牌者。true:A, false:B
index	出牌面值(CARDS的下标[0..N-1])
count	出牌张数([1-2])
*/
bool chupai(bool who, int& index, int& count, char* a, char* b)
{
	if (!who){//交换a b以简化后续操作
		swap(a,b);
	}

	index=0;
	for(; index<N && a[index]=='0'; index++){}
	int lastIndex=index;
	for(index++; index<N && a[index]=='0'; index++){}
	if (index==N){
		index=lastIndex;
	}

	count=a[index]=='1'?1:2;
	a[index]-=count;

	bool won=isAllZero(a);

	//调试
	{
		if(!who){
			swap(a,b);
		}
		cout<<(who?"A":"B");
		cout<<"出:["<<index<<"],"<<count<<"张"<<endl;
		cout<<"A:"<<a<<"\nB:"<<b<<endl;
	}

	return won;
}

/*
who		出牌者。true:A, false:B
index	上家所出牌面值(CARDS的下标[0..N-1])
count	上家所出牌张数([1-2])
*/
bool genpai(bool who, int& index, int& count, char* a, char* b)
{
	if (!who){//交换a b以简化后续操作
		swap(a,b);
	}

	for(index++; index<N && a[index]<'0'+count; index++){}
	if(index<N){//跟牌
		a[index]-=count;
	}
	else{//过
		index=-1;
	}

	bool won=isAllZero(a);

	//调试
	{
		if(!who){
			swap(a,b);
		}
		cout<<(who?"A":"B");
		if (index!=-1){
			cout<<"跟:["<<index<<"],"<<count<<"张"<<endl;
			cout<<"A:"<<a<<"\nB:"<<b<<endl;
		}
		else{
			cout<<"过";
			cout<<"\nA:"<<a<<"\nB:"<<b<<endl;
		}
	}

	return won;
}

char play(char* a, char* b)
{
	char winner=0;

	if (a && strlen(a)==N && b && strlen(b)==N){
		int index=-1, count;
		bool who=true;
		bool won;
		do 
		{
			won=((index==-1)? chupai(who,index,count,a,b): genpai(who,index,count,a,b));
			who=!who;//A、B轮流出牌/跟牌
		} while (!won);
		winner=!who?'A':'B';
	}

	return winner;
}

/*
输入:
1020301011040
1020301011042
输出:
0123456789012
1020301011040
1020301011042
--0123456789012
A:1020301011040
B:1020301011042
A出:[2],2张
A:1000301011040
B:1020301011042
B跟:[4],2张
A:1000301011040
B:1020101011042
A跟:[11],2张
A:1000301011020
B:1020101011042
B跟:[12],2张
A:1000301011020
B:1020101011040
A过
A:1000301011020
B:1020101011040
B出:[2],2张
A:1000301011020
B:1000101011040
A跟:[4],2张
A:1000101011020
B:1000101011040
B跟:[11],2张
A:1000101011020
B:1000101011020
A过
A:1000101011020
B:1000101011020
B出:[4],1张
A:1000101011020
B:1000001011020
A跟:[6],1张
A:1000100011020
B:1000001011020
B跟:[8],1张
A:1000100011020
B:1000001001020
A跟:[9],1张
A:1000100010020
B:1000001001020
B跟:[11],1张
A:1000100010020
B:1000001001010
A过
A:1000100010020
B:1000001001010
B出:[6],1张
A:1000100010020
B:1000000001010
A跟:[8],1张
A:1000100000020
B:1000000001010
B跟:[9],1张
A:1000100000020
B:1000000000010
A跟:[11],1张
A:1000100000010
B:1000000000010
B过
A:1000100000010
B:1000000000010
A出:[4],1张
A:1000000000010
B:1000000000010
B跟:[11],1张
A:1000000000010
B:1000000000000
A过
A:1000000000010
B:1000000000000
B出:[0],1张
A:1000000000010
B:0000000000000
赢家:B
请按任意键继续. . .
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值