【USACO2.3.3】和为零

【USACO2.3.3】和为零

Time Limit:10000MS  Memory Limit:65536K
Total Submit:9 Accepted:5 
Case Time Limit:1000MS

Description

  请考虑一个由 1 到 N ( N=3, 4, 5 ... 9 )的数字组成的递增数列:1 2 3 ... N。现在请在数列中插入“+”表示加,或者“-”表示减,抑或是“ ”表示空白,来将每一对数字组合在一起(请不在第一个数字前插入符号)。计算该表达式的结果并注意你是否得到了和为零。 

  请你写一个程序找出所有产生和为零的长度为N的数列。

Input

 单独的一行表示整数N (3 <= N <= 9)。

Output

 按照ASCII码的顺序,输出所有在每对数字间插入“+”, “-”, 或 “ ”后能得到和为零的数列。(注意:就算两个数字之间没有插入符号也应该保留空格)

Sample Input

 7

Sample Output

 1+2-3+4-5-6+7
 1+2-3-4+5+6-7
 1-2 3+4+5+6+7
 1-2 3-4 5+6 7
 1-2+3+4-5+6-7
 1-2-3-4-5+6+7

简单 的 DFS。。但是输出搞错了 一次。代码写的超烂。

下面是 AC代码 :
#include<iostream>
#include<algorithm>
using namespace std;

int a[10]={0,1,2,3,4,5,6,7,8,9};
int b[10];   //1代表“ ”空格,2代表+,3代表-。
int ans[10];
int n,i,j;
int ans_n;
int ans_val[1000];

void dfs(int cur){
	if(cur==n){
		int now=0,temp=1;
        int k=1;
		for(i=1;i<=n-1;i++){
			if(b[i]==1){
				if(temp>=0)
					temp=temp*10+(i+1);
				else
					temp=temp*10-(i+1);
			}
			else if(b[i]==2){
				ans[k++]=temp;
				temp=i+1;
				
			}
			else if(b[i]==3){
				ans[k++]=temp;
				temp=-(i+1);
			}
		}
		ans[k]=temp;
		
		for(i=1;i<=k;i++)
			now+=ans[i];
		
		if(now==0){
			int s=0;
			for(i=1;i<=n-1;i++)
				s=s*10+b[i];
			ans_val[ans_n++]=s;
		}
		
		
		return ;
	}
	b[cur]=1;
	dfs(cur+1);
	
	b[cur]=2;
	dfs(cur+1);
	
	b[cur]=3;
	dfs(cur+1);
}
int main(){	
	int temp[10];
	cin>>n;
	
	dfs(1);
	
	sort(ans_val,ans_val+ans_n);
	for(i=0;i<ans_n;i++){
		cout<<1;
		int l=1,t=ans_val[i];
		while(t){
			temp[l++]=t%10;
			t/=10;
		}
		for(j=n-1;j>=1;j--){
			if(temp[j]==1)
				cout<<" "<<n-j+1;
			else if(temp[j]==2)
				cout<<"+"<<n-j+1;
			else if(temp[j]==3)
				cout<<"-"<<n-j+1;
			
		}
		cout<<endl;
			
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值