201015 - 梭哈

题解byzzq_helloworld

也不知道大家有没有玩过这个扑克游戏,反正我没玩过。

说一说这道题的想法吧,其实本身也不难,就是一个暴力枚举,把所有牌型全部列出来,最后就可以得出结果了。

首先,定义一个牌(有花色和点数,代码如下:)

struct card {
  int f;//花色
  int n;//点数
} a[10],b[10];//a玩家和b玩家的牌

然后一个重载函数:

bool operator <(card a, card b)  {//重载函数
  return(a.n>b.n)||((a.n==b.n)&&(a.f>b.f));
}

接下来就是最重要的判断牌型了!!

bool StraightFlush(card t[]) {//同花顺
  for (int i = 1; i<5; i++)
	if ((t[i].f != t[i + 1].f) || (t[i].n != t[i + 1].n + 1))
	  return false;
  return true;
}

bool FourofaKind(card t[]) {//四条
  if(t[1].n==t[2].n && t[2].n==t[3].n && t[3].n==t[4].n)
	return true;
  if(t[2].n==t[3].n && t[3].n==t[4].n && t[4].n==t[5].n) {
	swap(t[1],t[5]);
	sort(t+1, t+5);
	return true;
  }
  return false;
}

bool FullHouse(card t[]) {//满堂红
  if(t[1].n==t[2].n && t[2].n==t[3].n && t[4].n==t[5].n)
	return true;
  if(t[1].n==t[2].n && t[3].n==t[4].n && t[4].n==t[5].n) {
	swap(t[1],t[5]);
	swap(t[2],t[4]);
	sort(t + 1, t + 4);
	sort(t + 4, t + 6);
	return true;
  }
  return false;
}

bool Flush(card t[]) {//同花
  for (int i = 1; i<5; i++)
	if (t[i].f != t[i + 1].f)
	  return false;
  return true;
}

bool Straight(card t[]) {//顺子
  for (int i = 1; i<5; i++)
	if (t[i].n != t[i + 1].n + 1)
	  return false;
  return true;
}

bool Threeofakind(card t[]) {//三条
  if (t[1].n == t[2].n && t[2].n == t[3].n)
	return true;
  if (t[2].n == t[3].n && t[3].n == t[4].n) {
	swap(t[1],t[2]);
	swap(t[2],t[3]);
	swap(t[3],t[4]);
	return true;
  }
  if (t[3].n == t[4].n && t[4].n == t[5].n) {
	swap(t[1],t[3]);
	swap(t[2],t[4]);
	swap(t[3],t[5]);
	swap(t[4],t[5]);
	return true;
  }
  return false;
}

bool TwoPairs(card t[]) {//两对
  if (t[1].n == t[2].n && t[3].n == t[4].n)
	return true;
  if (t[1].n == t[2].n && t[4].n == t[5].n) {
	swap(t[3],t[4]);
	swap(t[4],t[5]);
	return true;
  }
  if (t[2].n == t[3].n && t[4].n == t[5].n) {
	swap(t[1], t[2]);
	swap(t[2], t[3]);
	swap(t[3], t[4]);
	swap(t[4], t[5]);
	return true;
  }
  return false;
}

bool OnePair(card t[]) {//一对
  if (t[1].n == t[2].n)    return true;
  if (t[2].n == t[3].n) {
	swap(t[1], t[2]);
	swap(t[2], t[3]);
	return true;
  }
  if (t[3].n == t[4].n) {
	swap(t[1], t[3]);
	swap(t[2], t[4]);
	return true;
  }
  if (t[4].n == t[5].n) {
	swap(t[2], t[4]);
	swap(t[3], t[5]);
	swap(t[1], t[2]);
	swap(t[2], t[3]);
	return true;
  }
  return false;
}

这些就是判断牌型了,我们再来定义一个函数Count以便判断。

int Count(card t[]) {
  if((t[1].n==14)&&(t[2].n==5)&&(t[3].n==4)&&(t[4].n==3)&&(t[5].n==2))
	for(int i=1; i<=5; i++)
	  t[i].n = 6 - i;
	//判断牌型,返回数值
  if(StraightFlush(t)) return 9;
  else if(FourofaKind(t)) return 8;
  else if(FullHouse(t)) return 7;
  else if(Flush(t)) return 6;
  else if(Straight(t)) return 5;
  else if(Threeofakind(t)) return 4;
  else if(TwoPairs(t)) return 3;
  else if(OnePair(t)) return 2;
  else       return 1;
}

最后是main函数:

int main() {
  int i;
  while(cin>>a[1].n>>a[1].f) {//输入
	for (i = 2; i <= 5; i++)
	  scanf("%d%d", &a[i].n, &a[i].f);
	for (i = 1; i <= 5; i++)
	  scanf("%d%d", &b[i].n, &b[i].f);
	for (i = 1; i <= 5; i++) {
	  if (a[i].n == 1)
		a[i].n = 14;
	  if (b[i].n == 1)
		b[i].n = 14;
	  a[i].f = 5 - a[i].f;
	  b[i].f = 5 - b[i].f;
	}
	sort(a + 1, a + 6);//排序以便看牌型
	sort(b + 1, b + 6);
	int A=Count(a);//计算
	int B=Count(b);
	if(A>B)
	  cout<<"Player A win!\n";
	else if(A<B)
	  cout<<"Player B win!\n";
	else {//比较点数
	  for (i = 1; i <= 5; i++)
		if (a[i].n != b[i].n) {
		  if (a[i].n>b[i].n)
			cout<<"Player A win!\n";
		  if (a[i].n<b[i].n)
			cout<<"Player B win!\n";
		  break;
		}
	  if (i>5)
		cout<<"Player "<<(a[1].f>b[1].f?"A ":"B ")<<"win!\n";
	}
  }
  return 0;
}