算法:求这一数学题的解!

「已注销」
博客专家认证
2016-08-19 10:07:43
今天中午在公司群,看到他们讨论一数学题目,自己也试着写了求解。貌似这道题没有解么?有没有解不重要,重要的是,怎么样算才最合算?我就直接来一穷举,一一试探。貌似1到8没有解,如果数字可以给1到9的话,倒是有很多组解!


public class Main {

public static void main(String[] args) {
int[] numbers = new int[8];

//爆破开始
for(int i = 1; i <= 9; i++) {
for(int j = 1; j <= 9; j++) {
for(int k = 1; k <= 9; k++) {
for(int l = 1; l <= 9; l++) {
for(int m = 1; m <= 9; m++) {
for(int n = 1; n <= 9; n++) {
for(int p = 1; p <= 9; p++) {
for(int q = 1; q <= 9; q++) {
numbers[0] = i;
numbers[1] = j;
numbers[2] = k;
numbers[3] = l;
numbers[4] = m;
numbers[5] = n;
numbers[6] = p;
numbers[7] = q;

if(validate(numbers)) {
System.out.println(i + " + " + j +" = 9");
System.out.println(k + " - " + l + " = 1");
System.out.println(m + " + " + n + " = 7");
System.out.println(p + " - " + q + " = 2");
System.out.println("-------------------------");
}
}
}
}
}
}
}
}
}
}

private static boolean validate(int[] nums) {
//if是为了判断数值是否满足四个表达式
if( (nums[0] + nums[1] == 9) &&
(nums[2] - nums[3] == 1) &&
(nums[4] + nums[5] == 7) &&
(nums[6] - nums[7] == 2) ) {

//这个循环是为了判断是否有重复数字出现,查找算法
for(int i = 0; i < nums.length; i++) {
for(int j = i+1; j < nums.length; j++) {
if(nums[i] == nums[j]) {
return false;
}
}
}
return true;
}

return false;
}

}

穷举是无奈的办法了,所以想到csdn大神,给个另外的思路。当然算法与语言无关,但是csdn不能将同一问题发到不同板块。所以就选择java板块来发这个问题吧!
...全文
684 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
lovelystone 2016-08-23
  • 打赏
  • 举报
回复
楼上的思路是对的,只有(3个偶数、5个奇数) 或者(5个偶数、3个奇数)才能满足题目的要求,但是题目给出的可选值4个偶数、4个奇数,显然该题无解。
爱吃肉的Kerwin 2016-08-23
  • 打赏
  • 举报
回复
a-b=19 a+b=36 2a=45 a=22.5 由于a是6个正整数之和 所以此题无解
雷诺兹 2016-08-23
  • 打赏
  • 举报
回复
四个式子相加 得6个未知减去2个未知等于19,因为是四个奇数四个偶数,要么是奇数减奇数要么是偶数减偶数 显然是不可能等于奇数的 必然无解
showjim 2016-08-22
  • 打赏
  • 举报
回复
1+23=9 5-4=1 +7=7 8-6=2
tifacxbc 2016-08-22
  • 打赏
  • 举报
回复
引用 14 楼 hhv_01 的回复:
[quote=引用 13 楼 xiaoxing139 的回复:] 假设: A+B=9 C-D=1 E+F =7 G-H=2 则有(A+B)+(C-D)+(E+F)+(G-H)=9+1+7+2=19 又因为 A+B+C+D+E+F+G+H=1+2+3+4+5+6+7+8=36 第二个减去第一个得 2(D+H)=36-19=17 因为D+H不可能为小数 所以1~8的数不能满足,无解
[/quote] 的确是无解啊; 不过有种思路 2(D+H)=36-19=17 D+H=17/2 求出D和H 就好解了;;
  • 打赏
  • 举报
回复
引用 15 楼 syy19940213 的回复:
先不谈题目的问题。 给你提供一个算法思路,假设结果是有解。可以采用回溯算法。 额 具体回溯怎么实现,百度吧。 简单理解就是 敌进我退,敌退我打 解释就是: 如果试探结果正确,则进行下一步探测 比如 8 + 1 =9 正确,则继续算 7-6 = 1 正确 则继续计算 (敌退我打) 5+4=7 否,则返回到上一步。 (敌进我退) 从一条路往前走,能进则进,不能进则退回来,换一条路再试。直到找到一条路为止,当然也可能一条路都没有
另外,因为里面有减法, 所以试探的时候 从大到小试探, 加法没顺序,减法是有顺序的。
  • 打赏
  • 举报
回复
先不谈题目的问题。 给你提供一个算法思路,假设结果是有解。可以采用回溯算法。 额 具体回溯怎么实现,百度吧。 简单理解就是 敌进我退,敌退我打 解释就是: 如果试探结果正确,则进行下一步探测 比如 8 + 1 =9 正确,则继续算 7-6 = 1 正确 则继续计算 (敌退我打) 5+4=7 否,则返回到上一步。 (敌进我退) 从一条路往前走,能进则进,不能进则退回来,换一条路再试。直到找到一条路为止,当然也可能一条路都没有
HerveyHall 2016-08-22
  • 打赏
  • 举报
回复
引用 13 楼 xiaoxing139 的回复:
假设: A+B=9 C-D=1 E+F =7 G-H=2 则有(A+B)+(C-D)+(E+F)+(G-H)=9+1+7+2=19 又因为 A+B+C+D+E+F+G+H=1+2+3+4+5+6+7+8=36 第二个减去第一个得 2(D+H)=36-19=17 因为D+H不可能为小数 所以1~8的数不能满足,无解
scmod 2016-08-21
  • 打赏
  • 举报
回复
引用 9 楼 zhang5476499 的回复:
[quote=引用 7 楼 scmod 的回复:] 我想说这种题目不是忽悠人的么 又没说只能在1~8里选...结果的9172里面的9也能拿来用什么的...都是套路
括号里面是1到8,结果可以有9啊!还有,我自己也写了一算法求解,不过我的算法太冗长了,尤其是8个for循环,时间复杂度是O(n^8),所以问问有没有更优的算法。 还有,我的算法里面,for(i = 1; i <= 9, i++),说明我算得是1到9的范围,不过题目说是1到8.[/quote] 题目里并没有说括号里只能填1~8,只是说每个数字只能用一次,也没有说哪里的数字只能用一次,这种题目纯文字游戏没意义的... 你要硬要解,这道题穷举完了也没解,答案是3奇1偶,奇数结果必然是用掉1奇1偶才能得出,也就是你3奇的答案就用掉了3奇3偶,剩下1奇1偶你觉得有可能得到个结果是2不..... 不过算法什么的我不会,只能想到穷举的....复杂度感觉最高就4次啊..一脸懵逼
皎月明离人泪 2016-08-21
  • 打赏
  • 举报
回复
假设: A+B=9 C-D=1 E+F =7 G-H=2 则有(A+B)+(C-D)+(E+F)+(G-H)=9+1+7+2=19 又因为 A+B+C+D+E+F+G+H=1+2+3+4+5+6+7+8=36 第二个减去第一个得 2(D+H)=36-19=17 因为D+H不可能为小数 所以1~8的数不能满足,无解
「已注销」 2016-08-20
  • 打赏
  • 举报
回复
引用 4 楼 Vencc__ 的回复:
[quote=引用 3 楼 Vencc__ 的回复:] #include <iostream> int func(int mark[],int size,int arry[]) { switch(size){ case 0: for(int i=1;i<5;i++){ mark[i]=1; mark[9-i]=1; arry[0]=i; arry[1]=9-i; func(mark,2,arry); mark[i]=0; mark[9-i]=0; } break; case 2: for(int i=1;i<8;i++){ if(!mark[i]&&!mark[i+1]){ mark[i]=1; mark[i+1]=1; arry[2]=i; arry[3]=i+1; func(mark,4,arry); mark[i]=0; mark[i+1]=0; } } break; case 4: for(int i=1;i<4;i++){ if(!mark[i]&&!mark[7-i]){ mark[i]=1; mark[7-i]=1; arry[4]=i; arry[5]=7-i; func(mark,6,arry); mark[i]=0; mark[7-i]=0; } } break; case 6: for(int i=1;i<7;i++){ if(!mark[i]&&!mark[i+2]){ mark[i]=1; mark[i+2]=1; arry[6]=i; arry[7]=i+2; return 1; } } } return 0; } int main(){ int mark[9]={0}; int arry[8]={0}; int result=func(mark,0,arry); if(result){ for(int i=0;i<8;i++) printf("%d ",arry[i]); printf("\n"); }else{ printf("Impossible!\n"); } return 0; }
#include <iostream> int func(int mark[],int size,int arry[]) { switch(size){ case 0: for(int i=1;i<5;i++){ mark[i]=1; mark[9-i]=1; arry[0]=i; arry[1]=9-i; if(func(mark,2,arry)==1) return 1; mark[i]=0; mark[9-i]=0; } break; case 2: for(int i=1;i<8;i++){ if(!mark[i]&&!mark[i+1]){ mark[i]=1; mark[i+1]=1; arry[2]=i; arry[3]=i+1; if(func(mark,2,arry)==1) return 1; mark[i]=0; mark[i+1]=0; } } break; case 4: for(int i=1;i<4;i++){ if(!mark[i]&&!mark[7-i]){ mark[i]=1; mark[7-i]=1; arry[4]=i; arry[5]=7-i; if(func(mark,2,arry)==1) return 1; mark[i]=0; mark[7-i]=0; } } break; case 6: for(int i=1;i<7;i++){ if(!mark[i]&&!mark[i+2]){ mark[i]=1; mark[i+2]=1; arry[6]=i; arry[7]=i+2; return 1; } } } return 0; } int main(){ int mark[9]={0}; int arry[8]={0}; int result=func(mark,0,arry); if(result){ for(int i=0;i<8;i++) printf("%d ",arry[i]); printf("\n"); }else{ printf("Impossible!\n"); } return 0; } [/quote]以前在oj上面做过一些水题,不过还是想额外问问,代码的思路,用文字描述一下,大概步奏或者具体步骤之类的!
Vencc__ 2016-08-20
  • 打赏
  • 举报
回复
引用 3 楼 Vencc__ 的回复:
#include <iostream> int func(int mark[],int size,int arry[]) { switch(size){ case 0: for(int i=1;i<5;i++){ mark[i]=1; mark[9-i]=1; arry[0]=i; arry[1]=9-i; func(mark,2,arry); mark[i]=0; mark[9-i]=0; } break; case 2: for(int i=1;i<8;i++){ if(!mark[i]&&!mark[i+1]){ mark[i]=1; mark[i+1]=1; arry[2]=i; arry[3]=i+1; func(mark,4,arry); mark[i]=0; mark[i+1]=0; } } break; case 4: for(int i=1;i<4;i++){ if(!mark[i]&&!mark[7-i]){ mark[i]=1; mark[7-i]=1; arry[4]=i; arry[5]=7-i; func(mark,6,arry); mark[i]=0; mark[7-i]=0; } } break; case 6: for(int i=1;i<7;i++){ if(!mark[i]&&!mark[i+2]){ mark[i]=1; mark[i+2]=1; arry[6]=i; arry[7]=i+2; return 1; } } } return 0; } int main(){ int mark[9]={0}; int arry[8]={0}; int result=func(mark,0,arry); if(result){ for(int i=0;i<8;i++) printf("%d ",arry[i]); printf("\n"); }else{ printf("Impossible!\n"); } return 0; }
#include <iostream> int func(int mark[],int size,int arry[]) { switch(size){ case 0: for(int i=1;i<5;i++){ mark[i]=1; mark[9-i]=1; arry[0]=i; arry[1]=9-i; if(func(mark,2,arry)==1) return 1; mark[i]=0; mark[9-i]=0; } break; case 2: for(int i=1;i<8;i++){ if(!mark[i]&&!mark[i+1]){ mark[i]=1; mark[i+1]=1; arry[2]=i; arry[3]=i+1; if(func(mark,2,arry)==1) return 1; mark[i]=0; mark[i+1]=0; } } break; case 4: for(int i=1;i<4;i++){ if(!mark[i]&&!mark[7-i]){ mark[i]=1; mark[7-i]=1; arry[4]=i; arry[5]=7-i; if(func(mark,2,arry)==1) return 1; mark[i]=0; mark[7-i]=0; } } break; case 6: for(int i=1;i<7;i++){ if(!mark[i]&&!mark[i+2]){ mark[i]=1; mark[i+2]=1; arry[6]=i; arry[7]=i+2; return 1; } } } return 0; } int main(){ int mark[9]={0}; int arry[8]={0}; int result=func(mark,0,arry); if(result){ for(int i=0;i<8;i++) printf("%d ",arry[i]); printf("\n"); }else{ printf("Impossible!\n"); } return 0; }
Vencc__ 2016-08-20
  • 打赏
  • 举报
回复
#include <iostream> int func(int mark[],int size,int arry[]) { switch(size){ case 0: for(int i=1;i<5;i++){ mark[i]=1; mark[9-i]=1; arry[0]=i; arry[1]=9-i; func(mark,2,arry); mark[i]=0; mark[9-i]=0; } break; case 2: for(int i=1;i<8;i++){ if(!mark[i]&&!mark[i+1]){ mark[i]=1; mark[i+1]=1; arry[2]=i; arry[3]=i+1; func(mark,4,arry); mark[i]=0; mark[i+1]=0; } } break; case 4: for(int i=1;i<4;i++){ if(!mark[i]&&!mark[7-i]){ mark[i]=1; mark[7-i]=1; arry[4]=i; arry[5]=7-i; func(mark,6,arry); mark[i]=0; mark[7-i]=0; } } break; case 6: for(int i=1;i<7;i++){ if(!mark[i]&&!mark[i+2]){ mark[i]=1; mark[i+2]=1; arry[6]=i; arry[7]=i+2; return 1; } } } return 0; } int main(){ int mark[9]={0}; int arry[8]={0}; int result=func(mark,0,arry); if(result){ for(int i=0;i<8;i++) printf("%d ",arry[i]); printf("\n"); }else{ printf("Impossible!\n"); } return 0; }
isole、浩 2016-08-20
  • 打赏
  • 举报
回复
使用数组的全排列,如何满足条件就输出,结果是没有满足条件的吧。我在楼上用STL写的
isole、浩 2016-08-20
  • 打赏
  • 举报
回复
这题没结果吧,这种题用STL的全排列直接搞定了
#include <iostream>  
#include <algorithm> 
using namespace std;
int main(){
	int a[8]={1,2,3,4,5,6,7,8};
	while(next_permutation(a,a+8)){
		
		if((a[0]+a[1]==9)&&(a[2]-a[3]==1)&&(a[4]+a[5]==7)&&(a[6]-a[7]==2)){
			cout<<a[0]<<"  "<<a[1]<<"  "<<a[2]<<"  "<<a[3]<<" "<<a[4]<<" "<<a[5]<<" "<<a[6]<<" "<<a[7]<<endl;
		}			
	}
	return 0;
}
「已注销」 2016-08-20
  • 打赏
  • 举报
回复
引用 7 楼 scmod 的回复:
我想说这种题目不是忽悠人的么 又没说只能在1~8里选...结果的9172里面的9也能拿来用什么的...都是套路
括号里面是1到8,结果可以有9啊!还有,我自己也写了一算法求解,不过我的算法太冗长了,尤其是8个for循环,时间复杂度是O(n^8),所以问问有没有更优的算法。 还有,我的算法里面,for(i = 1; i <= 9, i++),说明我算得是1到9的范围,不过题目说是1到8.
Vencc__ 2016-08-20
  • 打赏
  • 举报
回复
#include <iostream> int func(int mark[],int size,int arry[]) { switch(size){ case 0://?+?=9 for(int i=1;i<5;i++){ mark[i]=1;//被选择的数字标记 mark[9-i]=1; arry[0]=i; arry[1]=9-i; if(func(mark,2,arry)==1) return 1;//找到就返回 mark[i]=0;//没找到就取消标记 mark[9-i]=0; } break; case 2://?-?=1 for(int i=1;i<8;i++){ if(!mark[i]&&!mark[i+1]){//判断数字是否被选择过 mark[i]=1; mark[i+1]=1; arry[2]=i; arry[3]=i+1; if(func(mark,2,arry)==1) return 1; mark[i]=0; mark[i+1]=0; } } break; case 4://?+?=7 for(int i=1;i<4;i++){ if(!mark[i]&&!mark[7-i]){ mark[i]=1; mark[7-i]=1; arry[4]=i; arry[5]=7-i; if(func(mark,2,arry)==1) return 1; mark[i]=0; mark[7-i]=0; } } break; case 6://?-?=2 for(int i=1;i<7;i++){ if(!mark[i]&&!mark[i+2]){ mark[i]=1; mark[i+2]=1; arry[6]=i; arry[7]=i+2; return 1; } } } return 0; } int main(){ int mark[9]={0}; int arry[8]={0}; int result=func(mark,0,arry); if(result){ for(int i=0;i<8;i++) printf("%d ",arry[i]); printf("\n"); }else{ printf("Impossible!\n"); } return 0; }
scmod 2016-08-20
  • 打赏
  • 举报
回复
我想说这种题目不是忽悠人的么 又没说只能在1~8里选...结果的9172里面的9也能拿来用什么的...都是套路
rickylin86 2016-08-20
  • 打赏
  • 举报
回复
1-8估计真的是没解的.

public class Test{
	public static void main(String[] args){
		int[] numbers = {1,2,3,4,5,6,7,8,9};
		process(numbers);
	}

	private static void process(int[] numbers){
		process(numbers,0);
	}

	private static void process(int[] numbers,int index){
		if(index == numbers.length){
			return ;
		}

		int temp = 0;
		for(int i = 0 ; i < numbers.length ; i ++){
			temp = numbers[index];
			numbers[index] = numbers[i];
			numbers[i] = temp;
			process(numbers,index + 1);
			temp = numbers[index];
			numbers[index] = numbers[i];
			numbers[i] = temp;
		}


		boolean condition1 = (numbers[0] + numbers[1] == 9);
		boolean condition2 = (numbers[2] - numbers[3] == 1);
		boolean condition3 = (numbers[4] + numbers[5] == 7);
		boolean condition4 = (numbers[6] - numbers[7] == 2);
		
		if(condition1&&condition2&&condition3&&condition4){
			System.out.printf("==============情况%d开始=============\n",++ count);
			System.out.printf("%d + %d = 9\n%d - %d = 1\n%d + %d = 7\n%d - %d = 2\n",numbers[0],numbers[1],numbers[2],numbers[3],numbers[4],numbers[5],numbers[6],numbers[7]);
			System.out.printf("==============情况%d结束=============\n",count);
		}

	}

	private static int count = 0;
}
「已注销」 2016-08-19
  • 打赏
  • 举报
回复
引用 1 楼 gnailgnailuil 的回复:
A+B=9 C-D=1 E+F=7 M-N=2 19+2D+2N=36 2D+2N=17 ???
前面条件 A+B=9 C-D=1 E+F=7 M-N=2满足就行了,后面的条件就不必了,但是有个前提,就是ABCDEFMN只能从1到8中取,而且1到8每个数只能用一次!
加载更多回复(1)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧