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;
}

目录
相关文章
|
5月前
|
算法 数据挖掘 大数据
深入解析力扣172题:阶乘后的零(计算因子5的方法详解及模拟面试问答)
深入解析力扣172题:阶乘后的零(计算因子5的方法详解及模拟面试问答)
|
5月前
|
移动开发 C++
【洛谷 P1157】组合的输出 题解(深度优先搜索+枚举子集)
该问题要求编程输出从1到n中选择r个元素的所有组合,组合按字典序排列。输入包含两自然数n和r(1&lt;n&lt;21, 0≤r≤n)。输出每个组合时,每个数字占据3个字符宽度。提供的AC代码使用C++,通过递归搜索方法枚举子集。样例输入为5 3,输出显示所有3个元素的组合。
49 0
|
6月前
|
Go C++
【力扣】2645. 构造有效字符串的最小插入数(动态规划 贪心 滚动数组优化 C++ Go)
【2月更文挑战第17天】2645. 构造有效字符串的最小插入数(动态规划 贪心 滚动数组优化 C++ Go)
44 8
|
6月前
|
存储
leetcode:415. 字符串相加(模拟竖式计算)
leetcode:415. 字符串相加(模拟竖式计算)
65 0
|
算法 测试技术 C++
剑指offer(C++)-JZ20:表示数值的字符串(算法-模拟)
剑指offer(C++)-JZ20:表示数值的字符串(算法-模拟)
|
存储 算法 容器
精选算法题(1)——枚举符合要求的算术表达式(DFS、回溯法)
精选算法题(1)——枚举符合要求的算术表达式(DFS、回溯法)
|
数据采集 算法 C++
DFS(深度优先搜索)详解(概念讲解,图片辅助,例题解释,剪枝技巧)
DFS(深度优先搜索)详解(概念讲解,图片辅助,例题解释,剪枝技巧)
1007 0
(枚举)(模拟)(前缀和)(数组模拟哈希)(可二分)1236. 递增三元组
(枚举)(模拟)(前缀和)(数组模拟哈希)(可二分)1236. 递增三元组
68 0
(模拟)(枚举)acwing蓝桥杯1245. 特别数的和
(模拟)(枚举)acwing蓝桥杯1245. 特别数的和
61 0
【每日一题Day101】LC1664生成平衡数组的方案数 | 预处理+枚举
给你一个整数数组 nums 。你需要选择 恰好 一个下标(下标从 0 开始)并删除对应的元素。请注意剩下元素的下标可能会因为删除操作而发生改变。
75 0