等式变换java解法

输入一个正整数X,在下面的等式左边的数字之间添加+号或者-号,使得等式成立。
1 2 3 4 5 6 7 8 9 = X
比如:
12-34+5-67+89 = 5
1+23+4-5+6-7-8-9 = 5
请编写程序,统计满足输入整数的所有整数个数。
输入:       正整数,等式右边的数字
输出:       使该等式成立的个数
样例输入:5

样例输出:21

package huawei;

import java.util.*;
/**
 * 从数的角度看
 * @author Administrator
 */
public class Equation1 {
	
	private static List<List<Integer>> list = new ArrayList<>();
	
	private static List<List<Integer>> op_list = new ArrayList<>();
	//如若元素不是有序的则需用到
	private static int [] ele = {1,2,3,4,5,6,7,8,9};
	
	private static int result = 5;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		getResult(result);
	}
	
	public static int getResult(int c) {
		fun(9);
		int count = 0;
		System.out.println(op_list.size());
		for(int k=0; k<list.size(); k++){
			Integer [] ee = new Integer[list.get(k).size()];
			op_list.clear();
			fun_op(list.get(k).toArray(ee), list.get(k).size()-1);
			//一组组合添加+或者-以后可能有的数组,计算其和
			for(int i=0; i<op_list.size(); i++){
				List<Integer> l = op_list.get(i);
				int sum = 0;
				for(int j=0; j<l.size(); j++){
					sum+=l.get(j);
				}
//				System.out.print(sum+" ");
				if(sum==result && l.get(0)>0){
					count++;
					System.out.println(l.toString());
				}
			}
		}
		System.out.println("count:"+count);
		return count;
	}
	//所有数字有可能的组合
	public static int fun(int c) {
		if(c==1){
			List gen = new ArrayList();
			gen.add(1);
			list.add(gen);
			return 1;
		}
		int r = 0;
		r = r + 2*fun(c-1);
		
		int k = list.size();
		for(int i=0; i<k; i++){
			List old = list.get(i);
			List gen = new ArrayList(old);
			gen.set(gen.size()-1, (int)(gen.get(gen.size()-1))*10 + c);
			list.add(gen);
			old.add(c);
		}
		return r;
	}
	//一组组合添加+或者-以后可能有的数组
	public static int fun_op(Integer [] arr, int c){
		if(c==0){
			List gen1 = new ArrayList();
			gen1.add(arr[c]);
			List gen2 = new ArrayList();
			gen2.add(-arr[c]);
			op_list.add(gen1);
			op_list.add(gen2);
			return 2;
		}
		int r = 0;
		r = r + fun_op(arr,c-1);
		
		int k = op_list.size();
		for(int i=0; i<k; i++){
			List old = op_list.get(i);
			List gen = new ArrayList(old);
			gen.add(-1*arr[c]);
			op_list.add(gen);
			old.add(arr[c]);
		}	
		return r;
	}
}

package huawei;

import java.util.ArrayList;
import java.util.List;
/**
 * 从符号的角度看
 * @author Administrator
 *
 */
public class Equation2 {
	
	private static List<List<Integer>> list = new ArrayList<>();
	
	private static List<List> op_list = new ArrayList<>();
	//如若元素不是有序的则需用到
	private static int [] ele = {1,2,3,4,5,6,7,8,9};
	
	private static char [] op = {'+','-',' '};

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		getResult(5);
	}
	
	public static int getResult(int c) {
		int count = 0;
		int r = fun_op(7);
		System.out.println("r:"+r);
		
		for(int i=0; i<op_list.size(); i++){
			List l = op_list.get(i);
			int sum = 0;
			
			StringBuffer sizi = new StringBuffer();
			sizi.append(ele[0]);
			
			int temp = ele[0];
			for(int j=0; j<l.size(); j++){
//				System.out.print(l.get(j));
				char o = (char) l.get(j);
				if(o=='+'){
					sizi.append("+");
				}else if(o=='-'){
					sizi.append("-");
				}
				sizi.append(ele[j+1]);
			}
			if(i<10){
				System.out.println(sizi);
			}
			if(sum==5){
				count++;
			}
		}
		System.out.println(count);
		return count;
	}
	//所有符号有可能的组合
	public static int fun_op(int c){
		if(c==0){
			for(char o: op){
				List gen = new ArrayList();
				gen.add(o);
				op_list.add(gen);
			}
			return 3;
		}
		int r = 0;
		r = r + 3*fun_op(c-1);
		
		int k = op_list.size();
		for(int i=0; i<k; i++){
			List old = op_list.get(i);
			List gen1 = new ArrayList(old);
			gen1.add(op[1]);
			List gen2 = new ArrayList(old);
			gen2.add(op[2]);
			op_list.add(gen1);
			op_list.add(gen2);
			old.add(op[0]);
		}
		return r;
	}
	
}

转载的解法

#include<iostream>  
#include<cstdio>  
using namespace std;  

int ops[21];  
const char sym[3] = {'+' , '-' , ' '};  
int result , num;  

void dfs(int layer, int currentResult, int lastOp, int lastSum)  
{  
	lastSum *= (layer > 9) ? 100 : 10;  
	lastSum += layer;  
	if(layer == 9)  
	{  
		currentResult += (lastOp) ? (-1 * lastSum) : lastSum;  
		if(currentResult == result)  
		{  
			++num;  
			printf("1");  
			for(int i = 2 ; i <= 9 ; ++i)  
			{  
				if(sym[ops[i-1]] != ' ')  
					printf(" %c ", sym[ops[i-1]]);  
				printf("%d", i);  
			}  
			printf(" = %d\n" , result);  
		}  
		return;  
	}  
	ops[layer] = 2;  
	dfs(layer + 1 , currentResult , lastOp , lastSum);   //Continue  
	currentResult += (lastOp)? (-1 * lastSum) : lastSum;  
	ops[layer] = 0;  
	dfs(layer + 1 , currentResult , 0 , 0);  //Plus  
	ops[layer] = 1;  
	dfs(layer + 1 , currentResult , 1 , 0);  //Minus  
}  

int main(void)  
{  
	while(scanf("%d", &result) != EOF)  
	{  
		num = 0;  
		dfs(1 , 0 , 0 , 0);  
		printf("%d\n" , num);  
	}  
	return 0;  
} 

这种代码最简单,关键是注意
currentResult += (lastOp)? (-1 * lastSum) : lastSum;  、

的位置,这是直接加上或者减去后面一个数。因为不能确定后面一个数是单独的数,还是作为下一个数的前一位,故要将“前一位”这种情况放到这句代码的前面递归,首先解决这种情况。

posted on 2015-01-22 16:27  长456风  阅读(491)  评论(0编辑  收藏  举报

导航