/**
* poj1950 DFS
* 很直接的dfs我也试过,就是生成一个符号序列,然后从左到右算一遍 这个没有问题,但是速度比较慢,8XXms
* 那我就考虑事先保存前面的结果,减少计算量,但是这个题有个类似于计算器的东西,从左往右走的话,会有优先级的问题,那DFS的时候也得小心这个
* 所以我的dfs函数就有四个参数,阶数、左操作数、右操作数和操作类型
* 初始化的时候,左操作数为1,右操作数为0,操作类型为空
* dfs的时候分成三种方向,如果下一个操作是+或-,那我先把当前输入的算式算出来,将结果作为left继续传递,而新输入的值,也就是step+1,作为右操作数加入
* 如果下一个操作是. 那如果我当前是空操作,那我就将左操作数和新输入的数合起来作为左操作数
* 不是空操作的话,那就将右操作数和新输入的数合起来作为右操作数
* 这个就比较类似于计算器了。阶数到了的时候输出,把算式算出结果,是0就累计计数,计数20以内就打印输出序列就好
*/
#include <cstdio>
const int MAX_NUM = 16;
int n;
int count = 0;
char op[MAX_NUM];//0 尚未处理 1 + 2 - 3 .
char op_table[4] = {' ','+','-','.'};
void dfs(int step,int left,int right,char o){
int res;
if(step == n){
if(o == 1){
res = left+right;
}
else if(o == 2){
res = left-right;
}
else{
res = left;
}
if(res == 0){
++count;
if(count <= 20){
for(int i=1;i<n;++i){
printf("%d %c ",i,op_table[op[i]]);
}
printf("%d\n",n);
}
}
return ;
}
int next=step+1;
if(o == 1){
res = left+right;
}
else if(o == 2){
res = left-right;
}
else{
res = left;
}
//+
op[step] = 1;
dfs(next,res,next,1);
//-
op[step] = 2;
dfs(next,res,next,2);
//.
op[step] = 3;
int power = (next>=10) ? 100 : 10;
if(o == 0){
dfs(next,left*power + next,0,o);
}
else{
dfs(next,left,right*power + next,o);
}
}
int main(){
scanf("%d",&n);
dfs(1,1,0,0);
printf("%d\n",count);
return 0;
}
poj1950 DFS
最新推荐文章于 2019-07-18 17:44:00 发布