P1473 [USACO2.3] 零的数列 Zero Sum

题目描述

请考虑一个由 1 到 N 的数字组成的递增数列:1,2,3,…,N。

现在请在数列中插入 + 表示加,或者 - 表示减,(空格) 表示空白(例如 1-2 3 就等于 1-23),来将每一对数字组合在一起(请不要在第一个数字前插入符号)。

计算该表达式的结果并判断其值是否为 0。 请你写一个程序找出所有产生和为零的长度为N的数列。

输入格式

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

输出格式

按照 ASCI I码的顺序,输出所有在每对数字间插入 +- (空格) 后能得到结果为零的数列。

输入输出样例

输入 #1

7

输出 #1

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

说明/提示

翻译来自NOCOW

USACO 2.3

①:

#include<bits/stdc++.h>
using namespace std;
const int N=25;
int n,a[10]={0,1,2,3,4,5,6,7,8,9};
char c[10],tmp[5]="  +-",s[N],ss[N];
int ls,lss;
int b[10];
char t[10];
bool check(){
	int num;
	num=sscanf(s+1,"%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d%c%d",&b[1],&t[1],&b[2],&t[2],&b[3],&t[3],&b[4],&t[4],&b[5],&t[5],&b[6],&t[6],&b[7],&t[7],&b[8],&t[8],&b[9]); 
    num=(num-1)/2;    //表示需要做几次运算
	int ans=b[1];
	for(int i=1;i<=num;++i){
		if(t[i]=='+') ans+=b[i+1];
		else ans-=b[i+1];
	} 
	if(ans==0) return 1;
	else return 0;
}
void dfs(int u){
	if(u>=n){    //n个数,需要n-1符号
	   ls=0,lss=0;
	   for(int i=1;i<=n;++i){
	   	   s[++ls]=a[i]+'0';
	   	   ss[++lss]=a[i]+'0';
	   	   if(c[i]!=' ' && i!=n) s[++ls]=c[i];
	   	   if(i!=n) ss[++lss]=c[i];    //同时存放s和ss数组 
	   } 
	   s[ls+1]=0;    //字符串结束,最后一个位置一定要赋值为0 
	   ss[lss+1]=0;
	   if(check())
	      printf("%s\n",ss+1);
	   return;
	}
	for(int i=1;i<=3;++i){    //枚举空格、+、-三个符号 
		c[u]=tmp[i];
		dfs(u+1); 
	}
}
int main(){
	cin>>n;
	dfs(1); 
	return 0;
}    //深搜 

②:

#include<bits/stdc++.h>
using namespace std;
int n,a[15],len;
char f[15];
bool check(){
	a[1]=1;len=1;    //第1个整数放1,当前有效数字个数为1 
	for(int i=1;i<=n-1;++i){    //枚举n-1个位置放置的符号 
	    if(f[i]==' '){    //如果符号为空格,说明当前的整数i+1和前一个整数是一个整体 
	    	a[len]=a[len]*10+(i+1);    //将当前整数i+1和前一个整数合并成新整数 
	    	continue;
	    }
	    else
	       a[++len]=i+1;    //如果不是空格,则将当前整数为新的整数 
	}
	int s=a[1],j=1;    //s表示表达式的值,第一个数一定是a[1] 
	for(int i=1;i<=n;++i){    //枚举所有的符号 
		if(f[i]=='+') s=s+a[++j];    //如果符号为+,则将当前新的算数a[++j]加入总和 
		if(f[i]=='-') s=s-a[++j];    //如果符号为-,则将当前新的算数a[++j]减去 
	}
	if(s==0) return 1;    //如果表达式的值为0,返回1 
	else return 0;
}
void shuchu(){    //输出 
	printf("1");    //输出第1个整数1 
	for(int i=1;i<=n-1;++i)    //枚举后面的n-1个位置
	    printf("%c%d",f[i],i+1);    //输出位置上的符号,和整数i+1 
	printf("\n");
}
void dfs(int u){    //即将放第u个位置的符号 
	if(u==n){    //当已经放了n-1个位置,因n个数间只有n-1个位置 
		if(check()==1) shuchu();    //如果计算的和为0
		return;
	}
	f[u]=' '; dfs(u+1);    //第u个位置放空格,再放下一个位置 
	f[u]='+'; dfs(u+1);
	f[u]='-'; dfs(u+1);
}
int main(){
	cin>>n;
	dfs(1); 
	return 0;
}   

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值