蓝桥杯(c语言)石头剪刀布 详解

【问题描述】

有N个小朋友在玩石头剪刀布的游戏(循环赛,任意两个人之间进行且只进行一局游戏)。现在已经知道了他们两两之间的输赢情况。

定义石头剪刀布局面为:有三个人i,j,k,满足:i赢了j,j赢了k,k赢了i,那么这个三元组(i,j,k)就被叫做石头剪刀布局面。

现在kAc想知道一共有多少个石头用剪刀布局面呢?

注意(i,j,k)(j,k,i) (k,i,j)被视为是相同的,之计数一次。

【输入格式】

第一行一个整数N。
  接下来N行每行N个字符。其中第i行的第j个字符可能是:
  -:表示i=j。
  Y:表示i赢了j。
  N:表示i输给了j。
  保证第i行的第j个字符和第j行的第i个字符,必然恰好一个是Y,另一个是N。

【输出格式】

一个整数,表示所求局面的数量。

【样例输入】

4
-YNN
N-YY
YN-Y
YNN-

【样例输出】

2

【过程分析】

共分为两步,第一步:

找出所有的石头剪刀布局面

1.对于输入的二维数组,i代表行数,j代表列数,从第0行开始遍历0到n-1列找出所有的Y,直到把n-1行遍历完毕,这一个操作是为了找出石头剪刀布局面的第一环,i赢了j。

2.在找到Y之后,再将j作为行数,开始遍历0到n-1列,找出所有的Y,将其列数标记为k,这一步是为了找出石头剪刀布局面的第二环,j赢了k。

3.标记了k之后,判断在二维数组中,下标为【k】【i】的值是否是Y,这一步是为了找出石头剪刀布局面的第三环,k赢了i。

这三步之后,下标为[i][j],[j][k],[k][i]的便符合石头剪刀布局面。

用一个二维数组将其存储起来,进行第二步。

第二步:

把重复的石头剪刀布局面删掉

记局面数为num,每当出现一个新局面时,操作默认局面数加一,把新局面与之前的num个局面进行比较,诺出现重复,跳出循环,局面书减一,即可达到删掉重复的局面数。

最后输出局面数。

具体详情见代码

#include<stdio.h>
int main(){
	int N;
	char outcome[10][10];
	scanf("%d",&N);
	getchar();            //因为后面要输入字符,必须用这一操作把scanf残留的回车去掉
	int i,j;
	 for(i=0;i<N;i++){
	 	for(j=0;j<N;j++){
	 		scanf("%c",&outcome[i][j]);
		 }
		 getchar();
	 }
	  int sign[120][3];        //存储石头剪刀布局面
	  int k,h,p,q,m;
	  int num=0;
	 for(i=0;i<N;i++){
	 	for(j=0;j<N;j++){
	 		if(outcome[i][j]=='Y'){
	 			for(k=0;k<N;k++){
	 				if(outcome[j][k]=='Y'){
	 					if(outcome[k][i]=='Y'){
	 						sign[num][0]=i;
	 						sign[num][1]=j;
	 						sign[num][2]=k;
	 						for(h=num-1;h>=0;h--){        //去掉重复的局面
	 							m=0;
							 	for(p=0;p<3;p++){
							 		for(q=0;q<3;q++){
							 			if(sign[num][p]==sign[h][q]){
							 				m++;
										 }
									 }
								 }
								 if(m==3){
								 	num--;
								 	break;
								 }
							 }
							 	num++;
						 }
					 }
				 }
			 }
		 }
	 }
	 printf("%d",num);
	return 0;
}

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零维展开智子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值