比赛排名--谁是凶手--可以喝多少水

计算正确的比赛排名

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。

思路分析

对于一个选手来说,有五种可能,五个选手,总共有5*5*5*5*5=pow(5,5)=3125种可能性。在这3125种可能性中,满足题设条件那种情况就是正确的排名顺序。

A选手说:B第二,我第三; 对于这一条语句,无非就两种情况,第一种:B第二(TRUE),A第三(FALSE),第二种:B第二(FALSE),A第三(TRUE)而逻辑真用1表示,逻辑假用0表示,那么A的表述用代码写成(b == 2) + (a == 3) == 1,以此类推。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main()
{
	for (int a = 1; a <= 5; a++)
	{
		for (int b = 1; b <= 5; b++)
		{
			for (int c = 1; c <= 5; c++)
			{
				for (int d = 1; d <= 5; d++)
				{
					for (int e = 1; e <= 5; e++)
					{
						if (((b == 2) + (a == 3) == 1)//
							&& ((b == 2) + (e == 4) == 1)//B
							&& ((c == 1) + (d == 2) == 1)//C
							&& ((c == 5) + (d == 3) == 1)//D
							&& ((e == 4) + (a == 1) == 1)//E
							//排除并列的情况,还可以使用a*b*c*d*e==120来排除并列情况。
							&& (a != b) && (a != c) && (a != d) && (a != e)
							&& (b != c) && (b != d) && (b != e) 
							&& (c != d) && (c != e) 
							&& (d != e))
						{
							printf("final result:a=%d,b=%d,c=%d,d=%d,e=%d\n",
							 a, b, c, d, e);
						}
					}
				}
			}
		}
	}
	system("pause");
	return 0;
}

这里写图片描述

谁是凶手

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯
的一个。以下为4个嫌疑犯的供词。
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。

思路分析

逻辑判断中,TRUE用数值1表示,FALSE用数值0表示。字符类型也可以进行数值运算,因为计算机中都是以ASCLL码存储的,A对应的ASCLL码值是65,以此类推,Z对应的ASCLL码值是90

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main()
{
	char killer=0;
	for(killer='A';killer<='D';killer++)
	{
		if(((killer!='A')+(killer=='C')+(killer=='D')+(killer!='D'))==3)
		{
			printf("%c\n",killer);
			break;
		}
	}
	system("pause");
	return 0;
}

这里写图片描述

可以喝多少水

1瓶汽水1元,2个空瓶可以换一瓶汽水,有20元,最多可以喝多少瓶汽水。

思路解析

设最多可以喝y瓶汽水,y=20+m,m是20个瓶子最多可以喝到的汽水,计算m。如果是偶数个空瓶,空瓶数/2得到本次空瓶换取的汽水数,下一次的来换汽水的空瓶数=这次的汽水数。如果是奇数个空瓶,(空瓶数-1)/2得到本次空瓶换取的汽水数,下一次的来换汽水的空瓶数=这次的汽水数+1,下一次的空瓶数要把这一次没换汽水的空瓶换掉。
递归解法

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>

unsigned  ExchangWater(unsigned money)
{
	int m = money;//一开始有多少钱就会有多少个空瓶
	if (m < 2)return 0;
	while (1 != m)
	{
		if (m & 1 == 1)//奇数个空瓶总共可以换取的汽水
			return ((m - 1) >> 1) + ExchangWater(((m - 1) >> 1) + 1);
			//采用位运算代替除法,提高运行效率
		else
			return (m>>1) + ExchangWater(m >> 1);
	}
	return 0;
}
int main()
{
	unsigned  money = 0;
	printf("请输入你有多少钱>\n");
	while (scanf("%d", &money))
		printf("你最多可以喝 %d 瓶汽水\n", money + ExchangWater(money));
	
	system("pause");
	return 0;
}

循环方法

凡是可以用递归实现的代码都可以用循环方式实现,递归方法运行可能会超时(在线编程一般都会有时间和内存的限制)。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>

int main()
{
	unsigned  money = 0;
	printf("请输入你有多少钱>\n");
	while (scanf("%d", &money))
	{
		int count = 0, water = 0;
		unsigned int bottle = money;
		while (bottle > 1)
		{
			//拿着空瓶去换汽水
			if ((bottle & 1) == 1)//奇数个空瓶
			{
				water = (bottle - 1) >> 1;
				bottle = water + 1;
			}
			else
			{
				water = bottle >> 1;
				bottle = water;
			}
			count += water;
		}
		printf("你可以喝 %d 汽水\n", money + count);
	}
	system("pause");
	return 0;
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值