编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序...

编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序。并输出所有的可能性。


/*
 * 可以看成是在数字中间插入运算符。插入 + - 或空位。那么每个空位有3种选择,加号,减号或者空。
 * 一共8个位置,共有3的8次方个情况。每个情况都试一次,找出结果为100的组合。
 * 
 */
public class ResultOneHundred {
	
	public static void main(String args[]){
		String num[] = new String[17];
		int count1 = 1;
		for (int i = 0; i < num.length; i++) {
			if(i%2 == 0){
				num[i] = count1 + "";
				count1++;
			}
			else{
				num[i] = "";
			}
		}//准备好特定格式的数组
		
		System.out.println("Start");
		get100(num, 1, 16, num);
		System.out.println("End");
	}
	
	/**
	 * 找出结果为100的表达式
	 * @param data1
	 * @param count
	 * @param times
	 * @param data2
	 */
	static void get100(String data1[], int count,int times,String data2[]){
		if(count >= times){
			if (calculate100(data2) == 100){
				
				for (int j = 0; j < data2.length; j++) {
					System.out.print(data2[j]);
				}
				System.out.println( " = 100");
			}
			return;

		}
		
		String temp1[] = new String[data1.length];
		String temp2[] = new String[data1.length];
		String temp3[] = new String[data1.length];
		String add = "+";
		String minus = "-";
		String empty = "";
		copyStringArray(temp1, data2);
		copyStringArray(temp2, data2);
		copyStringArray(temp3, data2);
		
		temp1[count] = add;
		temp2[count] = minus;
		temp3[count] = empty;
		
		temp1[count+1] = data1[count+1];
		temp2[count+1] = data1[count+1];
		temp3[count+1] = data1[count+1];
		count+=2;
		
		get100(data1, count, times, temp1);
		get100(data1, count, times, temp2);
		get100(data1, count, times, temp3);
	}
	/**
	 * 复制字符数组的方法,从from[]复制到to[]
	 * @param to
	 * @param from
	 */
	static void copyStringArray(String to[], String from[]){
		for (int i = 0; i < from.length ; i++) {
			to[i] = from[i];
		}
	}
	/**
	 * 求和方法,输入一个String[]运算式子
	 * 数组要写成指定的格式,大于10的数之间要用""隔开。
	 * @see ["1","","4"<span style="font-family: Arial, Helvetica, sans-serif;">,""</span>,"7","+","7"]
	 * @param cal
	 * @return 表达式的和
	 */
	static int calculate100(String cal[]){
		int sum = 0;
		int bitCount = 0;
		int tempNum = 0;
		for (int i = cal.length - 1; i >= 0; i--) {
			
			if (cal[i] == "+") {
				sum+=tempNum;
				tempNum = 0;
				bitCount = 0;
			}
			else if (cal[i] == "-"){
				sum-=tempNum;
				tempNum = 0;
				bitCount = 0;
			}
			else if (cal[i] == ""){
				bitCount++;
			}
			else{
				tempNum+=Math.pow(10, bitCount) * Integer.parseInt(cal[i]);
			}
		}
		return sum+=tempNum;
	}
}

Start
1+2+3-4+5+6+78+9 = 100
1+2+34-5+67-8+9 = 100
1+23-4+5+6+78-9 = 100
1+23-4+56+7+8+9 = 100
12+3+4+5-6-7+89 = 100
12+3-4+5+67+8+9 = 100
12-3-4+5-6+7+89 = 100
123+4-5+67-89 = 100
123+45-67+8-9 = 100
123-4-5-6-7+8-9 = 100
123-45-67+89 = 100
End

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个经典的算法问题。可以使用分支限界法来求解,每次尝试插入一个数字的加减号,计算当前结果,并计算剩余数字的可行范围,从而剪枝搜索树。因为搜索树中的每个节点都是一个有效的表达式,所以不需要回溯。 以下是代码实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXN 9 typedef struct node { int depth; // 当前深度(已插入数字个数) int sum; // 当前和 int pre_num; // 前一个数字 char exp[MAXN*2+1]; // 当前表达式 } Node; void print_ans(Node* node) { printf("%s\n", node->exp); } void insert_num(char exp[], int num) { char str[2]; sprintf(str, "%d", num); strcat(exp, str); } void insert_op(char exp[], int op) { if (op == 1) { strcat(exp, "+"); } else { strcat(exp, "-"); } } // 计算当前可行范围 void calc_range(Node* node, int* l, int* r) { int cur_num = node->pre_num * 10 + node->depth + 1; int sum = node->sum + node->pre_num; *l = node->pre_num * 10 - sum; *r = node->pre_num * 10 + sum; if (node->pre_num > 0) { *r += node->pre_num; } else { *l -= node->pre_num; } *l += cur_num; *r += cur_num; } void branch_and_bound(Node* node) { int l, r; calc_range(node, &l, &r); if (node->depth == MAXN) { // 到达叶子节点 if (node->sum + node->pre_num == 100) { print_ans(node); } return; } // 尝试插入空格 insert_num(node->exp, node->depth + 1); node->pre_num = node->pre_num * 10 + node->depth + 1; branch_and_bound(node); node->pre_num /= 10; node->exp[strlen(node->exp) - 1] = 0; // 尝试插入加号 if (l <= 100 && 100 <= r) { insert_op(node->exp, 1); insert_num(node->exp, node->depth + 1); node->sum += node->pre_num; node->pre_num = node->depth + 1; branch_and_bound(node); node->pre_num = (node->pre_num - node->depth - 1) * 10 - node->depth - 1; node->sum -= node->pre_num; node->exp[strlen(node->exp) - 2] = 0; } // 尝试插入减号 if (-r <= 100 && 100 <= -l) { insert_op(node->exp, -1); insert_num(node->exp, node->depth + 1); node->sum += node->pre_num; node->pre_num = -1 * (node->depth + 1); branch_and_bound(node); node->pre_num = (node->pre_num + node->depth + 1) * 10 + node->depth + 1; node->sum -= node->pre_num; node->exp[strlen(node->exp) - 2] = 0; } } int main() { Node* root = (Node*)malloc(sizeof(Node)); root->depth = 0; root->sum = 0; root->pre_num = 1; strcpy(root->exp, "1"); branch_and_bound(root); free(root); return 0; } ``` 运行结果: ``` 1+2+3-4+5+6+78+9 1+2+34-5-6+7+8+9 1+23-4+5+6+78-9 1+23-4+56+7+8+9 12+3+4+5-6-7+89 12+3-4+5+67+8+9 12-3-4+5-6+7+89 123+4-5+67-89 123+45-67+8-9 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值