USACO 2.3 Zero Sum(zerosum)

        这个题前几天看了,想是要用动态规划,当时没想到好的动态转移方程,就先放了放,不巧昨天晚上感冒了,今天拖着疲惫的身体做这个题,想还是用枚举吧,反正最大仅仅3^8=6561种情况,肯定不会超时的。思路就是枚举数字之间的符号(“ ”、“+”、“-”),然后对表达式进行计算,可以使用栈,数字栈中将中间有空格的两个数或多个数计算成为一个数,符号栈中去除空格字符,然后必然数字栈的元素比字符栈中元素数多1。从栈底向栈顶计算,b[i]和b[i+1]经过符号c[i]的运算,值保存在b[i+1]中,最后栈顶元素就是该表达式的计算结果,检验结果是否为0,是0则将此完整的表达式化为string类型存进set<string>中自动排序,最后输出即可。

 

/*
ID: jzzlee1
PROG:zerosum
LANG:C++
*/
//#include<iostream>
#include<fstream>
#include<cstring>
#include<set>
#include<string>
using namespace std;
ifstream cin("zerosum.in");
ofstream cout("zerosum.out");
set<string> set1;
int main()
{
	short n,d[10];
	cin>>n;
	int a[10]={0,1,2,3,4,5,6,7,8,9},b[10];
	int i;
	for(d[8]=0;n>=9?d[8]<=2:d[8]==0;++d[8])
		for(d[7]=0;n>=8?d[7]<=2:d[7]==0;++d[7])
			for(d[6]=0;n>=7?d[6]<=2:d[6]==0;++d[6])
				for(d[5]=0;n>=6?d[5]<=2:d[5]==0;++d[5])
					for(d[4]=0;n>=5?d[4]<=2:d[4]==0;++d[4])
						for(d[3]=0;n>=4?d[3]<=2:d[3]==0;++d[3])
							for(d[2]=0;d[2]<=2;++d[2])
								for(d[1]=0;d[1]<=2;++d[1])
								{
									int c[10];
									for(i=0;i<=n;i++)
									{
										b[i]=i;
										c[i]=d[i];
									}
									int j=1;int count=0;
									for(i=1;i!=n;++i)
										if(c[j]==1)
											++j;
										else if(c[j]==2)
											++j;
										else
										{
											count++;
											b[j]=10*b[j]+b[j+1];
											for(int k=j;k<n-count;++k)
											{
												b[k+1]=b[k+2];
												c[k]=c[k+1];
											}
										}
 										for(i=1;i!=n-count;++i)
											if(c[i]==1)
												b[i+1]+=b[i];
											else
												b[i+1]=b[i]-b[i+1];
										if(b[i]==0)
										{
											string str("1");
											for(j=1;j!=n;j++)
											{
												switch(d[j])
												{
												case 0:
													str+=" ";break;
												case 1:
													str+="+";break;
												case 2:
													str+="-";break;
												}
												str+=j+1+'0';
											}
											set1.insert(str);
										}
								}
								set<string>::iterator iter;
								for(iter=set1.begin();iter!=set1.end();++iter)
									cout<<*iter<<endl;
								return 0;
}

你可能感兴趣的:(USACO)