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

简介:
/*
这个代码运行的时间长主要是因为每次枚举之后都要重新计算一下和的值!
如果要快的话,应该在dfs,也就是枚举的过程中计算出前边的数值(这种方法见第二个代码),直到最后,这样不必每一次枚举都要从头再算一遍值!
*/
1
#include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 7 char ch[20]; 8 char sign[3]={'+', '-', '.'}; 9 int n, cnt; 10 int num[20]; 11 int signNum[200]; 12 13 void dfs(int u){ 14 if(u==n){ 15 if(signNum['+']==n-1 || signNum['+']+signNum['.']==n-1 || signNum['.']==n-1 || signNum['-']==n-1) return; 16 for(int i=1; i<n; ++i){ 17 num[i]=i; 18 if(ch[i]=='.'){ 19 int s=i, v=i; 20 while(i<n && ch[i]=='.'){ 21 if(i+1>9) 22 s=s*100+(++i); 23 else s=s*10+(++i); 24 } 25 if(s>10000) return ;//非得加上这句话....然后就幸运的过了! 26 num[v]=s; 27 --i; 28 } 29 } 30 num[n]=n; 31 int s=num[1]; 32 for(int i=1; i<n; ++i) 33 if(ch[i]!='.'){ 34 if(ch[i]=='+') s+=num[i+1]; 35 else s-=num[i+1]; 36 } 37 if(s==0){ 38 ++cnt; 39 if(cnt<=20){ 40 for(int i=1; i<n; ++i) 41 printf("%d %c ", i, ch[i]); 42 printf("%d\n", n); 43 } 44 } 45 return; 46 } 47 for(int i=0; i<3; ++i){ 48 ch[u]=sign[i]; 49 ++signNum[sign[i]]; 50 dfs(u+1); 51 --signNum[sign[i]]; 52 } 53 } 54 55 int main(){ 56 while(scanf("%d", &n)!=EOF){ 57 cnt=0; 58 dfs(1); 59 printf("%d\n", cnt); 60 } 61 return 0; 62 }
复制代码

 

复制代码
 /*
清晰的思路,清晰的代码.....T^T!
*/
1
#include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 char sign[3]={'+', '-', '.'}; 7 int n, cnt; 8 char ch[20]; 9 int dir[2]={10, 100}; 10 11 12 //pre记录的是'+' 或者是 '-'的左边的运算值, nowI记录的是其右边的值 13 void dfs(char chPre, int pre, int nowI, int cur){ 14 if(cur==n){ 15 int s=-1; 16 if(chPre=='+') 17 s=pre+(nowI*dir[cur/10]+cur); 18 else if(chPre=='-') 19 s=pre-(nowI*dir[cur/10]+cur); 20 //如果chPre=='.' 说明整个式子中不存在运算符号+或者-, 那最终的结果一定不是0 21 if(s==0){ 22 ++cnt; 23 if(cnt<=20){ 24 for(int i=1; i<n; ++i) 25 printf("%d %c ", i, ch[i]); 26 printf("%d\n", n); 27 } 28 } 29 return ; 30 } 31 for(int i=0; i<3; ++i){ 32 ch[cur]=sign[i]; 33 if(ch[cur]!='.'){ 34 if(chPre=='+') 35 dfs(ch[cur], pre+(nowI*dir[cur/10]+cur), 0, cur+1); 36 else if(chPre=='-') 37 dfs(ch[cur], pre-(nowI*dir[cur/10]+cur), 0, cur+1); 38 else dfs(ch[cur], pre*dir[cur/10]+cur, 0, cur+1); 39 } 40 else{ 41 //之前出现了运算符,当前不是运算符 42 if(chPre=='+' || chPre=='-')//一直累计nowI的值 43 dfs(chPre, pre, nowI*dir[cur/10]+cur, cur+1); 44 else //如果之前没有出现过运算符+或者-,一直累计pre的值 45 dfs(chPre, pre*dir[cur/10]+cur, 0, cur+1); 46 } 47 } 48 } 49 50 int main(){ 51 while(scanf("%d", &n)!=EOF){ 52 cnt=0; 53 dfs(' ', 0, 0, 1); 54 printf("%d\n", cnt); 55 } 56 return 0; 57 }
复制代码









本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/3955021.html,如需转载请自行联系原作者
目录
相关文章
|
5月前
【每日一题Day345】LC2562找出数组的串联值 | 模拟
【每日一题Day345】LC2562找出数组的串联值 | 模拟
19 0
|
5月前
|
存储 机器学习/深度学习 Windows
【题型总结】模拟运算
【题型总结】模拟运算
29 0
|
5月前
|
前端开发
【每日一题Day228】LC2460对数组执行操作 | 模拟+双指针
【每日一题Day228】LC2460对数组执行操作 | 模拟+双指针
19 0
|
5月前
|
存储 C++
数据的存储练习题 -- (解题思路+代码)
数据的存储练习题 -- (解题思路+代码)
36 0
|
5月前
|
机器学习/深度学习 算法 测试技术
C++前缀和算法的应用:向下取整数对和 原理源码测试用例
C++前缀和算法的应用:向下取整数对和 原理源码测试用例
|
7月前
|
存储 算法 容器
精选算法题(1)——枚举符合要求的算术表达式(DFS、回溯法)
精选算法题(1)——枚举符合要求的算术表达式(DFS、回溯法)
|
9月前
|
数据采集 算法 C++
DFS(深度优先搜索)详解(概念讲解,图片辅助,例题解释,剪枝技巧)
DFS(深度优先搜索)详解(概念讲解,图片辅助,例题解释,剪枝技巧)
111 0
(模拟)(枚举)acwing蓝桥杯1245. 特别数的和
(模拟)(枚举)acwing蓝桥杯1245. 特别数的和
45 0
(枚举)(模拟)(前缀和)(数组模拟哈希)(可二分)1236. 递增三元组
(枚举)(模拟)(前缀和)(数组模拟哈希)(可二分)1236. 递增三元组
47 0
(树状数组,线段树)(数组模拟哈希)(解题步骤)acwing数星星
(树状数组,线段树)(数组模拟哈希)(解题步骤)acwing数星星
67 0