完成等式:1 2 3 4 5 6 7 8 9=X

<pre name="code" class="cpp">/*
有一个未完成的等式:1 2 3 4 5 6 7 8 9=X
当给出整数N的具体值后,请你在2,3,4,5,6,7,8,9这8个数字的每一个前面,或插入运算符号“+”,或插入一个运算符号“-”,或不插入任何运算符号,使等式成立,并统计出能使等式成立的算式总数,若无解,则输出0。
例如:取X为108时,共能写出15个不同的等式,以下就是其中的二个算式:
1+23+4+56+7+8+9=108
123-45+6+7+8+9=108
输入一个数X
输出一个数,表示能使等式成立的算式总数。
*/
/*
解题思路:最重要的是如何处理不插入任何符号是的情况,可以认为不插入符号也相当于插入符号#,这个符号的运算性质是num1 # num2 = num1*10 + num2;
这样三种符号就分别对应(#,+,-)-->(0,1,2),但是这种运算不太好进行,最好能够转化为一般的加减法(dealWithSpace())
*/


#include<iostream>
using namespace std;


long num[9]={1,2,3,4,5,6,7,8,9};
int op[8];//对应八个符号位
int opb[8];//对op的符号的备份




//将自定义符号转化为加号:向前扫描到非零数num[k],然后num[k]=10*num[k]+op[i+1],操作数置为0,符号#变为+(对应1)
//1#2 =--> num:12 0  ; op:+(对应1)
//1#2#3--->12+0#3-->123+0+0 = 123
//1#2-3#4-->12+0-34--->12+0-34+0 = -22;
void dealWithSpace(){
	int k;
	int i;
	for(i=0;i<8;i++){
		if(op[i]==0){
			op[i] = 1;
			k = i;
			while(k>=0 && num[k]==0) k--;
			if(k<0){
				num[i+1] = 0;
				continue;
			}
			if(num[k]!=0){
				num[k] = num[k]*10+num[i+1];
				num[i+1] = 0;
			}			
		}
	}
}
//对数1~9构成的数组,按转换后的操作符,进行运算,此时只有加减法了
long calculate(){
	int i;
	long res = num[0];
	for(i=0;i<8;i++){
		if(op[i]==1){
			res += num[i+1];
		}else{//op[i]==2
			res -= num[i+1];
		}
	}
	return res;
}
//每个符号位对应3种情况:#,+,-
int fun(long x){
	int count = 0;
	int i;
	long res;
	int n0,n1,n2,n3,n4,n5,n6,n7;
	for(n0=0;n0<=2;n0++){
		op[0] = n0;opb[0] = n0;
		for(n1=0;n1<=2;n1++){
			op[1] = n1;opb[1] = n1;
			for(n2=0;n2<=2;n2++){
				op[2] = n2;	opb[2] = n2;
				for(n3=0;n3<=2;n3++){
					op[3] = n3;	opb[3] = n3;
					for(n4=0;n4<=2;n4++){
						op[4] = n4;	opb[4] = n4;
						for(n5=0;n5<=2;n5++){
							op[5] = n5;	opb[5] = n5;
							for(n6=0;n6<=2;n6++){
								op[6] = n6;	opb[6] = n6;	
								for(n7=0;n7<=2;n7++){
									op[7] = n7;	opb[7] = n7;


									for(i=0;i<9;i++){
										num[i] = i+1;
									}


									dealWithSpace();
									res = calculate();
									if(res==x){		
										count++;
										for(i=0;i<8;i++){
											cout<<num[i];
											if(op[i]==1)
												cout<<'+';
											else if(op[i]==2)
												cout<<'-';
										}
										cout<<num[8];
										cout<<"\t";
										cout<<res;
										cout<<endl;
										//cin>>i;
									}
								
									/*/检验输出
									for(i=0;i<9;i++){
										cout<<num[i]<<" ";
									}
									cout<<"\t";
									for(i=0;i<8;i++){
										cout<<opb[i];
									}
									cout<<"\t";
									for(i=0;i<8;i++){
										cout<<op[i];
									}
									cout<<"\t";
									cout<<res;
									cout<<endl;
									cin>>i;
									*//检验输出
									//recover:don't forget 
									for(i=0;i<8;i++){
										op[i] = opb[i];
									}
								}
							}
						}
					}
				}
			}		
		}
	}
	return count;
}


void main(){
	long x;
	cin>>x;
	cout<<fun(x);
	cout<<endl;
}

转载请说明出处!

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值