今日头条面试算法题——确定ABCDE五个学校名次

题目描述:

A、B、C、D、E五个学校,A说E是第一,B说B是第二,C说A是最差的,D说C不是最好的,E说D是最好的。只有第一和第二名说的是对的,其他说的都是错的,请编程确定五个学校的名次。

先上代码,再说思路。

代码:

#include <stdio.h>

int main() {
	int a, b, c, d, e;
	int val = 0;
	int flag = 1;
	int cnt = 0;
	for(a = 1; a <= 5; a++)
		for(b = 1; b <= 5; b++)
			for(c = 1; c <= 5; c++)
				for(d = 1; d <= 5; d++)
					for(e = 1; e <= 5; e++)
						if(((a == 2) && (e == 1)) + 
								(b == 2) + 
								(((c == 1) || (c == 2)) && (a == 5)) + 
								(((d == 1) || (d == 2)) && (c != 1)) + 
								(((e == 1) || (e == 2)) && (d == 1))
									== 2) {
							val = 0;
							flag = 1;
							cnt = 0;
							
							val |= (1 << (a-1));
							val |= (1 << (b-1)); 
							val |= (1 << (c-1));
							val |= (1 << (d-1));
							val |= (1 << (e-1));
							while(val) {
								if(val%2 == 0) 
									flag = 0;
								val /= 2;
								cnt++;
							}
							if(flag == 1 && cnt == 5) {
								printf("a=%d b=%d c=%d d=%d e=%d\n", a, b, c, d, e);
							}
						}
	return 0;
}

思路:

每个学校的名次是1~5范围之间,所以采用5个for var=1 to 5的循环来表示每个学校的可能名次(这算是暴力破解吧,还请大神指正另外的思路)。在最内层循环中,利用if条件判断语句描述题目中的说法,例如:((c == 1) || (c == 2)) && (a == 5),该语句表示c若满足是第一名或第二名,那么c说的是真话,a此时就应该是最差的。比较特殊的有:1、(a == 2) && (e == 1),这是因为a == 1,若为真的话,e就不能为1;2、b == 2,b自己说自己是第二,要么是真话,要么是假话,也不能匹配其他条件。剩余的两个条件相信大家也能类似的推出来。

那么在这几个判断条件中,只有两个人说了真话,所以将这5个判断条件相加应该等于2,表示这五个条件中,有2个人说了真话。

进入if条件中后,我们用val的五个位分别表示每个学校可能的名次,只有满足val的后5位是全1的才能说明a、b、c、d、e分别隶属于不同的名次,不然肯定有某几个学校的名次是重合的。接下来我们就用while(val)循环判断val的后5位是否是全1。flag标志为0表示后5位某一位为0,不满足我们的条件。cnt是确保确实while循环执行了5次,因为在测试的过程中发现,仅根据flag标识会漏判末尾连续全1,但高位存在0的情况,比如:00001。

当判断最后5位全1的条件满足时,我们就输出符合条件的情况:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值