
一道C++面试题,100分求高手们解答,谢谢!
假设有一种游戏规则,使用两副牌,有三种牌型,对子,单张,顺子(三个及三个以上相连的牌视为顺子:例如3,4,5或10,J,Q,K,A)2不参与顺子,即A,2,3或2,3,4...
假设有一种游戏规则,使用两副牌,有三种牌型,对子,单张,顺子(三个及三个以上相连的牌视为顺子:
例如3,4,5或10,J,Q,K,A)
2不参与顺子,即A,2,3或2,3,4都不成顺
A跟在K后面成顺,即J,Q,K,A为顺子
玩家跟牌时出的牌数要跟第一个出牌的玩家数量相同,并且有对要跟对,有顺子要跟顺子
现在第一个玩家已经出了牌,出的牌型为三种牌型中的一种,轮到你出牌,请实现判断能否出牌的函数
//整数0-12分别表示A,2,3,4,5,6,7,8,9,10,J,Q,K
//handpai为你手中的牌,handlen为牌张数
//firstpai为第一个出牌的玩家所出的牌,firstlen为出的张数
//outpai为你出的牌,outlen为出的牌的张数
//返回true表示outpai及outlen符合规则,否则返回false
bool CanOut(const int handpai[],int handlen,const int firstpai[],int firstlen, const int
outpai[],int outlen);
//测试用例
#include ...
int main()
{
int handpai[10] = {1,2,3,3,4,7,7,8,9,9};
int firstpai[3] = {3,4,5};
int outpai[3] = {1,2,3};
bool canout = CanOut(handpai,10,firstpai,3,outpai,3);
assert(!canout); //2不能参与顺子
}
1、手里的牌是否都已排序?
2、出的牌是否已排序?
3、是否第一个玩家不能出0张牌?
4、就用你给的main函数测试就行吗? 展开
例如3,4,5或10,J,Q,K,A)
2不参与顺子,即A,2,3或2,3,4都不成顺
A跟在K后面成顺,即J,Q,K,A为顺子
玩家跟牌时出的牌数要跟第一个出牌的玩家数量相同,并且有对要跟对,有顺子要跟顺子
现在第一个玩家已经出了牌,出的牌型为三种牌型中的一种,轮到你出牌,请实现判断能否出牌的函数
//整数0-12分别表示A,2,3,4,5,6,7,8,9,10,J,Q,K
//handpai为你手中的牌,handlen为牌张数
//firstpai为第一个出牌的玩家所出的牌,firstlen为出的张数
//outpai为你出的牌,outlen为出的牌的张数
//返回true表示outpai及outlen符合规则,否则返回false
bool CanOut(const int handpai[],int handlen,const int firstpai[],int firstlen, const int
outpai[],int outlen);
//测试用例
#include ...
int main()
{
int handpai[10] = {1,2,3,3,4,7,7,8,9,9};
int firstpai[3] = {3,4,5};
int outpai[3] = {1,2,3};
bool canout = CanOut(handpai,10,firstpai,3,outpai,3);
assert(!canout); //2不能参与顺子
}
1、手里的牌是否都已排序?
2、出的牌是否已排序?
3、是否第一个玩家不能出0张牌?
4、就用你给的main函数测试就行吗? 展开
4个回答
展开全部
1,2 既然是面试题 可以理解成已经排好序,只要实现主要的部分就可以了
3 可以在程序中加一个判断 如果为0则弹出
4 这个main只是一个特例,可以用这个测试,但是例子改变时要求程序也能通过运行
我想想 一会再贴答案
答案出炉~ 半小时 唉
#include "iostream.h"
#include "assert.h"
#include "string.h"
bool CanOut(const int handpai[],int handlen,const int firstpai[],int firstlen, const int outpai[],int outlen)
{
bool ret = false;
int exist = 0;
if(firstlen == 0 ) //如果出牌为0 弹出错误提示 可以出牌
{
cout<<"firstpai is 0, wrong!";
ret = true;
}
else if(firstlen == 1) //如果出牌为1,表示单张
{
if(outlen != firstlen) //判断出牌的张数和第一个出牌张数是否相同
return false;
for(int i=0;i<handlen;i++)
{
if(outpai[0] == handpai[i]) //判断出的牌是否存在于手中(若类似于qq牌则该步骤可取消)
{
exist++;
break;
}
}
if(exist != 0 && outpai[0]>firstpai[0] && ((outpai[0] == 0 || outpai[0] == 1)
|| (outpai[0] != 0 && outpai[0] != 1))) //判断如果出的牌比first牌大则出牌成功
{
ret = true;
}
}
else if(firstlen == 2) //出牌为对子,和单张相似
{
if(outlen != firstlen)
return false;
for(int i=0;i<handlen-1;i++)
{
if(outpai[0] == handpai[i] && outpai[1] == handpai[i+1])
{
exist++;
break;
}
}
if(exist != 0 && outpai[0]>firstpai[0] && ((outpai[0] == 0 || outpai[0] == 1)
|| (outpai[0] != 0 && outpai[0] != 1)))
{
ret = true;
}
}
else //出牌为顺子
{
if(outlen != firstlen)
return false;
for(int j=0; j<outlen; j++)
{
for(int i=0;i<handlen;i++)
{
if(outpai[j] == handpai[i]) //判断牌是否存在手中
{
exist++;
break;
}
}
if(outpai[j] == 1) // 如果存在‘2’ 则返回错误
return false;
if(j != outlen-1) //如果出的牌不连续,则返回错误
{
if((outpai[j+1]-outpai[j]) != 1 || (outpai[j+1]-outpai[j]) != -12)
{
return false;
}
}
}
if(exist == firstlen
&& outpai[0]>firstpai[0] && ((outpai[0] == 0 || outpai[0] == 1)
|| (outpai[0] != 0 && outpai[0] != 1)))
{
ret = true;
}
}
return ret;
}
int main()
{
int handpai[10] = {1,2,3,3,4,7,7,8,9,9};
int firstpai[3] = {3,4,5};
int outpai[3] = {1,2,3};
bool canout = CanOut(handpai,10,firstpai,3,outpai,3);
//assert(!canout); //2不能参与顺子
if (canout == true)
cout<<"can";
else
cout<<"can not";
getchar();
}
3 可以在程序中加一个判断 如果为0则弹出
4 这个main只是一个特例,可以用这个测试,但是例子改变时要求程序也能通过运行
我想想 一会再贴答案
答案出炉~ 半小时 唉
#include "iostream.h"
#include "assert.h"
#include "string.h"
bool CanOut(const int handpai[],int handlen,const int firstpai[],int firstlen, const int outpai[],int outlen)
{
bool ret = false;
int exist = 0;
if(firstlen == 0 ) //如果出牌为0 弹出错误提示 可以出牌
{
cout<<"firstpai is 0, wrong!";
ret = true;
}
else if(firstlen == 1) //如果出牌为1,表示单张
{
if(outlen != firstlen) //判断出牌的张数和第一个出牌张数是否相同
return false;
for(int i=0;i<handlen;i++)
{
if(outpai[0] == handpai[i]) //判断出的牌是否存在于手中(若类似于qq牌则该步骤可取消)
{
exist++;
break;
}
}
if(exist != 0 && outpai[0]>firstpai[0] && ((outpai[0] == 0 || outpai[0] == 1)
|| (outpai[0] != 0 && outpai[0] != 1))) //判断如果出的牌比first牌大则出牌成功
{
ret = true;
}
}
else if(firstlen == 2) //出牌为对子,和单张相似
{
if(outlen != firstlen)
return false;
for(int i=0;i<handlen-1;i++)
{
if(outpai[0] == handpai[i] && outpai[1] == handpai[i+1])
{
exist++;
break;
}
}
if(exist != 0 && outpai[0]>firstpai[0] && ((outpai[0] == 0 || outpai[0] == 1)
|| (outpai[0] != 0 && outpai[0] != 1)))
{
ret = true;
}
}
else //出牌为顺子
{
if(outlen != firstlen)
return false;
for(int j=0; j<outlen; j++)
{
for(int i=0;i<handlen;i++)
{
if(outpai[j] == handpai[i]) //判断牌是否存在手中
{
exist++;
break;
}
}
if(outpai[j] == 1) // 如果存在‘2’ 则返回错误
return false;
if(j != outlen-1) //如果出的牌不连续,则返回错误
{
if((outpai[j+1]-outpai[j]) != 1 || (outpai[j+1]-outpai[j]) != -12)
{
return false;
}
}
}
if(exist == firstlen
&& outpai[0]>firstpai[0] && ((outpai[0] == 0 || outpai[0] == 1)
|| (outpai[0] != 0 && outpai[0] != 1)))
{
ret = true;
}
}
return ret;
}
int main()
{
int handpai[10] = {1,2,3,3,4,7,7,8,9,9};
int firstpai[3] = {3,4,5};
int outpai[3] = {1,2,3};
bool canout = CanOut(handpai,10,firstpai,3,outpai,3);
//assert(!canout); //2不能参与顺子
if (canout == true)
cout<<"can";
else
cout<<"can not";
getchar();
}
展开全部
#include<algorithm>//排序用
#include<string.h>//清零用
bool CanOut(int* handpai,int handlen,int* firstpai,int firstlen,int* outpai,int outlen)
{
int i;
int cnt[14],tempfirst[110],tempout[110];
for (i=1;i<handlen;i++) if (handpai[i]<handpai[i-1]) return false;//手上牌非排好序返回假
for (i=1;i<outlen;i++) if (outpai[i]<outpai[i-1]) return false;//出的牌非排好序返回假
if (!firstlen) return false;//第一玩家出0张牌,返回假
if (firstlen!=outlen) return false;//牌数不等返回假
memset(cnt,0,sizeof(cnt));//进行统计判定要出的牌是否自己手上所拥有的,计数器清零
for (i=0;i<handlen;i++)
if (handpai[i]==0) cnt[13]++;//1当做比K大1的值
else cnt[handpai[i]]++;
for (i=0;i<14;i++) if (cnt[i]>8) return false;//超出两副牌
for (i=0;i<outlen;i++)//对于要出的牌看看数目是否超出拥有的
if (outpai[i]==0)
{
if (!cnt[13]) return false;
else cnt[13]--;
tempout[i]=13;
}
else
{
if (!cnt[outpai[i]]) return false;
else cnt[outpai[i]]--;
tempout[i]=outpai[i];
}
for (i=0;i<firstlen;i++)
if (firstpai[i]==0) tempfrist[i]=13;
else tempfirst[i]=firstpai[i];
std::sort(tempfirst,tempfirst+firstlen);//临时存储第一玩家出的牌,进行排序
std::sort(tempout,tempout+outlen);//临时存储自己要出的牌,进行排序
if (firstlen==1) return tempfirst[0]<tempout[0];//只出一张牌的判定
else if (firstlen==2) return tempfirst[0]==tempfirst[1]&&tempout[0]==tempout[1]&&tempfirst[0]<tempout[0];//一个对子的判定
else if (tempfirst[0]==1||tempout[0]==1) return false;//剩下顺子的情况,是不可以有2存在的
else
{
for (i=1;i<firstlen;i++) if (tempfirst[i]<=tempfirst[i-1]) return false;//判定第一玩家出的牌是否构成顺子
for (i=1;i<outlen;i++) if (tempout[i]<=tempout[i-1]) return false;//判定自己出的牌是否构成顺子
return tempout[0]>tempfirst[0];//判定顺子大小
}
}
#include<string.h>//清零用
bool CanOut(int* handpai,int handlen,int* firstpai,int firstlen,int* outpai,int outlen)
{
int i;
int cnt[14],tempfirst[110],tempout[110];
for (i=1;i<handlen;i++) if (handpai[i]<handpai[i-1]) return false;//手上牌非排好序返回假
for (i=1;i<outlen;i++) if (outpai[i]<outpai[i-1]) return false;//出的牌非排好序返回假
if (!firstlen) return false;//第一玩家出0张牌,返回假
if (firstlen!=outlen) return false;//牌数不等返回假
memset(cnt,0,sizeof(cnt));//进行统计判定要出的牌是否自己手上所拥有的,计数器清零
for (i=0;i<handlen;i++)
if (handpai[i]==0) cnt[13]++;//1当做比K大1的值
else cnt[handpai[i]]++;
for (i=0;i<14;i++) if (cnt[i]>8) return false;//超出两副牌
for (i=0;i<outlen;i++)//对于要出的牌看看数目是否超出拥有的
if (outpai[i]==0)
{
if (!cnt[13]) return false;
else cnt[13]--;
tempout[i]=13;
}
else
{
if (!cnt[outpai[i]]) return false;
else cnt[outpai[i]]--;
tempout[i]=outpai[i];
}
for (i=0;i<firstlen;i++)
if (firstpai[i]==0) tempfrist[i]=13;
else tempfirst[i]=firstpai[i];
std::sort(tempfirst,tempfirst+firstlen);//临时存储第一玩家出的牌,进行排序
std::sort(tempout,tempout+outlen);//临时存储自己要出的牌,进行排序
if (firstlen==1) return tempfirst[0]<tempout[0];//只出一张牌的判定
else if (firstlen==2) return tempfirst[0]==tempfirst[1]&&tempout[0]==tempout[1]&&tempfirst[0]<tempout[0];//一个对子的判定
else if (tempfirst[0]==1||tempout[0]==1) return false;//剩下顺子的情况,是不可以有2存在的
else
{
for (i=1;i<firstlen;i++) if (tempfirst[i]<=tempfirst[i-1]) return false;//判定第一玩家出的牌是否构成顺子
for (i=1;i<outlen;i++) if (tempout[i]<=tempout[i-1]) return false;//判定自己出的牌是否构成顺子
return tempout[0]>tempfirst[0];//判定顺子大小
}
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你想问什么...
把自己手里的牌按号码整理成一个二维数组,其他的处理就很容易了...
把自己手里的牌按号码整理成一个二维数组,其他的处理就很容易了...
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
确实有点难度
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询