poj 1950 Dessert(dfs枚举,模拟运算过程)

简介:

/*
     这个代码运行的时间长主要是因为每次枚举之后都要重新计算一下和的值!
    如果要快的话,应该在dfs,也就是枚举的过程中计算出前边的数值(这种方法见第二个代码),直到最后,这样不必每一次枚举都要从头再算一遍值!
 */
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

char ch[20];
char sign[3]={'+', '-', '.'}; 
int n, cnt;
int num[20];
int signNum[200];

void dfs(int u){
    if(u==n){
       if(signNum['+']==n-1 || signNum['+']+signNum['.']==n-1 || signNum['.']==n-1 || signNum['-']==n-1) return;
       for(int i=1; i<n; ++i){           
               num[i]=i;
               if(ch[i]=='.'){
                 int s=i, v=i;
                 while(i<n && ch[i]=='.'){
                     if(i+1>9)
                      s=s*100+(++i);
                    else s=s*10+(++i);
                 }
                 if(s>10000) return ;//非得加上这句话....然后就幸运的过了!
                 num[v]=s;
                 --i;
            }
       }
       num[n]=n;
       int s=num[1];
       for(int i=1; i<n; ++i)
             if(ch[i]!='.'){
               if(ch[i]=='+') s+=num[i+1];
               else s-=num[i+1];
          }
       if(s==0){
               ++cnt;
               if(cnt<=20){
                   for(int i=1; i<n; ++i)
                      printf("%d %c ", i, ch[i]);
                   printf("%d\n", n);
               }
       }
       return;
     }
    for(int i=0; i<3; ++i){
        ch[u]=sign[i];
        ++signNum[sign[i]];
        dfs(u+1);
        --signNum[sign[i]];
    }
}

int main(){
    while(scanf("%d", &n)!=EOF){
        cnt=0;
        dfs(1);
        printf("%d\n", cnt);
    }
    return 0;
}


/*
    清晰的思路,清晰的代码.....T^T!
 */
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
char sign[3]={'+', '-', '.'};
int n, cnt;
char ch[20];
int dir[2]={10, 100};


//pre记录的是'+' 或者是 '-'的左边的运算值, nowI记录的是其右边的值 
void dfs(char chPre, int pre, int nowI, int cur){
    if(cur==n){
        int s=-1;
        if(chPre=='+')
            s=pre+(nowI*dir[cur/10]+cur);
        else if(chPre=='-')
              s=pre-(nowI*dir[cur/10]+cur);
        //如果chPre=='.' 说明整个式子中不存在运算符号+或者-, 那最终的结果一定不是0 
        if(s==0){
            ++cnt;
            if(cnt<=20){
                for(int i=1; i<n; ++i)
                    printf("%d %c ", i, ch[i]);
                printf("%d\n", n);
            }
        }
        return ;
    }
    for(int i=0; i<3; ++i){
        ch[cur]=sign[i];
        if(ch[cur]!='.'){
            if(chPre=='+')
                dfs(ch[cur], pre+(nowI*dir[cur/10]+cur), 0, cur+1);
            else if(chPre=='-')
                dfs(ch[cur], pre-(nowI*dir[cur/10]+cur), 0, cur+1);
            else dfs(ch[cur], pre*dir[cur/10]+cur, 0, cur+1);
        }
        else{
            //之前出现了运算符,当前不是运算符 
            if(chPre=='+' || chPre=='-')//一直累计nowI的值 
                dfs(chPre, pre, nowI*dir[cur/10]+cur, cur+1);
            else //如果之前没有出现过运算符+或者-,一直累计pre的值 
                dfs(chPre, pre*dir[cur/10]+cur, 0, cur+1);
        }
    }
}

int main(){
    while(scanf("%d", &n)!=EOF){    
        cnt=0;
        dfs(' ', 0, 0, 1);
        printf("%d\n", cnt);
    } 
    return 0;
}

目录
相关文章
|
9月前
【每日一题Day345】LC2562找出数组的串联值 | 模拟
【每日一题Day345】LC2562找出数组的串联值 | 模拟
49 0
|
8月前
|
移动开发 C++
【洛谷 P1157】组合的输出 题解(深度优先搜索+枚举子集)
该问题要求编程输出从1到n中选择r个元素的所有组合,组合按字典序排列。输入包含两自然数n和r(1&lt;n&lt;21, 0≤r≤n)。输出每个组合时,每个数字占据3个字符宽度。提供的AC代码使用C++,通过递归搜索方法枚举子集。样例输入为5 3,输出显示所有3个元素的组合。
74 0
|
9月前
|
算法 测试技术 C++
【数论】【分类讨论】【C++算法】1611使整数变为 0 的最少操作次数
【数论】【分类讨论】【C++算法】1611使整数变为 0 的最少操作次数
|
9月前
|
存储 Python
处理随机元素来创建数列是一个涉及随机数生成和数列构造的过程
处理随机元素来创建数列是一个涉及随机数生成和数列构造的过程
83 0
|
算法 测试技术 C++
剑指offer(C++)-JZ20:表示数值的字符串(算法-模拟)
剑指offer(C++)-JZ20:表示数值的字符串(算法-模拟)
(枚举)(模拟)(前缀和)(数组模拟哈希)(可二分)1236. 递增三元组
(枚举)(模拟)(前缀和)(数组模拟哈希)(可二分)1236. 递增三元组
85 0
|
算法 测试技术 C++
蓝桥杯第八讲--枚举与模拟【例题】(一)
蓝桥杯第八讲--枚举与模拟【例题】
180 0
蓝桥杯第八讲--枚举与模拟【例题】(一)
蓝桥杯第八讲--枚举与模拟【例题】(二)
蓝桥杯第八讲--枚举与模拟【例题】
187 0
蓝桥杯第八讲--枚举与模拟【例题】(二)
|
Python
考点:函数参数传参、求和、奇数、偶数、输入输出、range步长灵活使用【Python习题04】
考点:函数参数传参、求和、奇数、偶数、输入输出、range步长灵活使用【Python习题04】
185 0
|
人工智能 Java
Java练习小题_求一个3*3矩阵对角线元素之和,矩阵的数据用行的形式输入到计算机中 程序分析:利用双重for循环控制输入二维数组,再将a[i][i]累加后输出。
Java练习小题_求一个3*3矩阵对角线元素之和,矩阵的数据用行的形式输入到计算机中 程序分析:利用双重for循环控制输入二维数组,再将a[i][i]累加后输出。
492 0
Java练习小题_求一个3*3矩阵对角线元素之和,矩阵的数据用行的形式输入到计算机中 程序分析:利用双重for循环控制输入二维数组,再将a[i][i]累加后输出。