• 算法练习(三)


    一、侦察队问题

    某侦察队接到一项紧急任务,要求在A、B、C、D、E、F六个队员中尽可能多地挑若干人,但有以下限制条件:

    1)A和B两人中至少去一人;

    2)A和D不能一起去;

    3)A、E和F三人中要派两人去;

    4)B和C都去或都不去;

    5)C和D两人中去一个;

    6)若D不去,则E也不去。

    试编写一个程序,输出问应当让哪几个人去?

    代码

    #include<stdio.h>
    
    int main() {
    	int a[6],b[6][6],i,sum=0,k=0; // a[0]~a[5]分别代表A~F。其值为0,代表不在队伍中;为1,代表在队伍中
    	for (a[0] = 0; a[0] < 2; a[0]++) { // A
        for (a[1] = 0; a[1] < 2; a[1]++) { // B
    	for (a[2] = 0; a[2] < 2; a[2]++) { // C
    	for (a[3] = 0; a[3] < 2; a[3]++) { // D
    	for (a[4] = 0; a[4] < 2; a[4]++) { // E
    	for (a[5] = 0; a[5] < 2; a[5]++) { // F
    		if ((a[0]||a[1]) && !(a[0]&&a[3]) && ((a[0]&&a[4]&&!a[5])||(a[0]&&!a[4]&&a[5])||(!a[0]&&a[4]&&a[5])) && ((a[1]&&a[2])||(!a[1]&&!a[2])) && ((a[2]&&!a[3])||(!a[2]&&a[3])) && (a[3]||!a[4])) {  // 进行逻辑判断,符合题目所给逻辑,则计算队伍人数并存储在二维数组中。
    		    for (i = 0; i < 6; i++) {
    		    	if (a[i] == 1) {
    		    		sum++;					
    	    		}			
    			}
    			for (i = 0; i < 6; i++) {
    				b[sum][i] = a[i]; // 第一个下标为队伍总人数
    			}
    			if (sum > k) { // 刷新符合要求的最大人数
    				k = sum;
    			}
    		}
    	}}}}}
    	sum = 0;
    	}
    	// 从A~F依次表示其是否在队伍中
    	for (i = 0; i < 6; i++) {
    		printf("%d ",b[k][i]);
    	}
    	printf("
    ");
    	return 0;
    }
    

    解题思路

    将六个人是否在队伍中的状态0(不在)1(在)来表示。暴力其所有可能的情况,判断每种情况是否满足条件,满足则统计其个数,并储存。最后输出人数最多组的安排情况。

    要点

    表示此题6个逻辑要求是此题的要点。表示方法为:

    1. A和B两人中至少去一人 ——> a[0] || a[1]
    2. A和D不能一起去 ——> !(a[0]&&a[3])
    3. A、E和F三人中要派两人去 ——> (a[0]&&a[4]&&!a[5]) || (a[0]&&!a[4]&&a[5]) || (!a[0]&&a[4]&&a[5])
    4. B和C都去或都不去 ——> (a[1]&&a[2]) || (!a[1]&&!a[2])
    5. C和D两人中去一个 ——> (a[2]&&!a[3]) || (!a[2]&&a[3])
    6. 若D不去,则E也不去 ——> a[3] || !a[4]

    有个更好的方式表示该题逻辑

    if(a+b>=1&&a+d!=2&&a+e+f==2&&b==c&&c+d==1&&(d+e==0||d==1))
    

    这样更简单。但是我没想到。。。

    二、奇怪的分式

    上小学的时候,小明经常自己发明新算法。一次,老师出的题目是:1/4 乘以 8/5

    小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45

    老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼!

    对于分子、分母都是1~9中的一位数的情况,还有哪些算式可以这样计算呢?
    请写出所有不同算式的个数(包括题中举例的)。
    显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。

    但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!

    注意:答案是个整数(考虑对称性,肯定是偶数)。

    代码

    #include<stdio.h>
    
    int main() {
        int a,b,c,d,sum = 0;
    	for (a = 1; a < 10; a++) {
    	for (b = 1; b < 10; b++) {
    	for (c = 1; c < 10; c++) {
    	for (d = 1; d < 10; d++) {
    		if (a != b && c != d) {  // 确保两个分式的分子与分母都不相同 
    			if ((a*c)*(b*10 + d) == (b*d)*(a*10 + c)) {
    				sum++;
    			}
    		}
    	}}}}
    	printf("%d",sum);
    	return 0;
    }
    

    解题思路

    题目的思路简单,遍历所有情况,满足条件则进行计数。
    题目的要点在于变化方程形式,将除法的比较转变为乘法的比较。这样可以避免整型相除的误差。

    附:python代码:

    sum = 0
    for a in range(1,10):
    	for b in range(1,10):
    		for c in range(1,10):
    			for d in range(1,10):
    				if a != b and c != d:    #确保两个分式的分子与分母都不相同 
    				    if (a*c)*(b*10 + d) == (b*d)*(a*10 + c):
    				    	sum+=1
    print(sum)
    

    附:Shape Of My Heart

    以上

  • 相关阅读:
    结对编程收获
    《程序员修炼之道》读书笔记
    《梦断代码》读书笔记
    《编程珠玑》和《梦断代码》(部分) 读书笔记
    团队项目个人心得
    团队项目Alpha阶段心得感悟
    第9周读书笔记
    第8周读书笔记
    结对编程收获
    第七周读书笔记
  • 原文地址:https://www.cnblogs.com/mxwbq/p/7142363.html
Copyright © 2020-2023  润新知