算法竞赛入门经典 (第二版)习题2-6

用 1,2,3 …9组成三个数字abc,def,ghi每个数字恰好使用一次,要求 abc:def:ghi = 1:2:3按照 abc def ghi 的格式输出所有解 ,每行一个解。

思路 :有a,b,c三个变量,先确定a的范围,最小的数且符合题目规定的数字为123,最大的数字且符合题目规定的数字是987 ,所以a的范围是 123 ~ 329(987/3).最简单的确定比例的做法就是将其乘以某数,所以b = 2a,c=3a;比例的问题怎么确定?最简单的方法就是采用判断;首先a的各位数字不能相等,其次b的各位数字不能相等且不能等于a的各位数字,最后c的各位数字不能相等且不能等于a和b的各位数字(a,b,c的各位数字都不能出现0)

#include <stdio.h>
int main(){
	int a=101,b,c;
	while(a < 330){
		if( a%10==a/100 || a%10==a/10%10 || a/100==a/10%10
		    && a%10 != 0 && a/10%10!=0 && a/100 !=0 ){
			a++;
			continue ;
		}
		b = a * 2 ;
		c = a * 3 ;
		if(b/a==2 && b%a==0){
			if(b%10 !=a%10 &&b%10 != a/10%10 &&b%10!=a/100 &&                //b的个位不等于a的各位数字 
			   b/10%10 !=a%10 && b/10%10 != a/10%10 && b/10%10!=a/100 &&     //b的十位不等于a的各位 
			   b/100 !=a%10 && b/100 != a/10%10 && b/100!=a/100              //b的百位不等于a的各位 
			   && b%10!=b/10%10 && b%10!=b/100 && b/10%10!=b/100             //b的每位数字互不相等 
			   && b%10 != 0 && b/10%10!=0 && b/100 !=0                       //b的各位数字不等于零 
			){
				if(c%10 !=a%10 &&c%10 != a/10%10 &&c%10!=a/100                //c的每位数字都不等于a和b的每位数字 
			     &&c/10%10 !=a%10 && c/10%10 != a/10%10 && c/10%10!=a/100 
			     &&c/100 !=a%10 && c/100 != a/10%10 && c/100!=a/100 
			     &&c%10 !=b%10 &&c%10 != b/10%10 &&c%10!=b/100 
			     &&c/10%10 !=b%10 && c/10%10 != b/10%10 && c/10%10!=b/100 
			     &&c/100 !=b%10 && c/100 != b/10%10 && c/100!=b/100
			     && c%10!=c/10%10 && c%10!=c/100 && c/10%10!=c/100            //c的每位互不相等 
			     &&c%10 != 0 && c/10%10!=0 && c/100 !=0){                     //c的每位不等于0 
			   	printf("a:%d b:%d c:%d\n",a,b,c);
			   }
			}
		}
		a++;
	}
	return 0;
}

其实这个方法确实有点麻烦
看了很多办法,其中有的人采用将a,b,c每个数字加起来看是否等于45(1+2+3+…+9),这个方法有漏洞,加起来和等45的组合有很多;借鉴了一下别人的方法保证每个数字只会出现一次就是将a,b,c的每个数保存到一个数组中,从小到大进行排序,接着判断相邻的两个数字是否相等,并且要保证数组的每个数字不等于零。
TOPsnap 的原文链接:点击这里
源码:

#include <stdio.h>
int main(){
	int a = 123 ,b,c,i,j;
	int array[9];
	while(a < 329){
		b = a*2;
		c = a*3;
		array[0] = a%10 ; array[1] = a/10%10; array[2] = a/100;
		array[3] = b%10 ; array[4] = b/10%10; array[5] = b/100;
		array[6] = c%10 ; array[7] = c/10%10; array[8] = c/100;
		for(i=0;i<9;i++){
			for(j=i+1;j<9;j++){
				if(array[i]>array[j]){
					int temp = array[i];
					array[i] = array[j];
					array[j] = temp ;
				}
			}
		}
		for(i=0,j=1;i<9&&j<9;i++,j++){
			if(array[i] == array[j] ||array[i]==0 || array[j]==0) break;
		}
		if(j == 9)printf("%d %d %d\n",a,b,c);
		a++;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
算法竞赛是一个非常有趣和具有挑战性的领域,对于入门者来说,掌握一些经典习题是非常重要的。下面是一些算法竞赛入门经典习题的讲解: 1. 两数之和:给定一个整数数组和一个目标值,在数组中找出和为目标值的两个数。可以假设每个输入都只有一个解,并且同一个元素不能使用两次。这个问题可以使用哈希表来解决,时间复杂度为O(n)。 2. 最大子序和:给定一个整数数组,找到一个具有最大和的连续子数组。例如,对于数组[-2,1,-3,4,-1,2,1,-5,4],其最大子序和为6(子数组为[4,-1,2,1])。这个问题可以使用动态规划来解决,时间复杂度为O(n)。 3. 两数相加:给定两个非空链表,表示两个非负整数。它们每位数字都是按照逆序方式存储的,并且每个节点只能存储一位数字。将这两个数相加并以相同形式返回一个新的链表。例如,输入(2 -> 4 -> 3) + (5 -> 6 -> 4),输出7 -> 0 -> 8。这个问题可以使用链表的基本操作来解决,时间复杂度为O(max(m,n)),其中m和n分别是两个链表的长度。 4. 最长回文子串:给定一个字符串,找到其中最长的回文子串。例如,对于字符串"babad",最长的回文子串为"bab"或"aba"。这个问题可以使用动态规划或中心扩展法来解决,时间复杂度为O(n^2)。 5. 叉树的最大深度:给定一个叉树,找出其最大深度。最大深度是从根节点到最远叶子节点的最长路径上的节点数。例如,对于叉树[3,9,20,null,null,15,7],其最大深度为3。这个问题可以使用递归来解决,时间复杂度为O(n),其中n是叉树中的节点数。 以上是一些算法竞赛入门经典习题的讲解,希望能对你有所帮助。在算法竞赛中,不仅要熟悉各种经典题目的解法,还要注重实践和思考,提高自己的编程能力和算法思维。祝你在算法竞赛中取得好成绩!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值