深度优先搜索2-Shredding Company(算法基础 第7周)
2016-06-19 14:18
816 查看
问题描述:
分析
题目中有一点感觉题意表达不是特别清晰:就是分割数字中不能用前导0(比如0123),但是它没说是否可以理解为:0, 123。从答案来看应该是不可以这样。
刚开始做的时候算法中忽略了所有0的存在,后来发现有问题调来调去,已经懵逼了。而且在POJ上测试,这道题还没有提供测试输入、输出。先跳过吧,贴一个别人的正确答案和自己的待完善答案。
源码
正确答案来自:http://blog.csdn.net/challengerrumble/article/details/47397825
自己的待修改答案:
分析
题目中有一点感觉题意表达不是特别清晰:就是分割数字中不能用前导0(比如0123),但是它没说是否可以理解为:0, 123。从答案来看应该是不可以这样。
刚开始做的时候算法中忽略了所有0的存在,后来发现有问题调来调去,已经懵逼了。而且在POJ上测试,这道题还没有提供测试输入、输出。先跳过吧,贴一个别人的正确答案和自己的待完善答案。
源码
正确答案来自:http://blog.csdn.net/challengerrumble/article/details/47397825
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; int num[7],tmp[7],len,mm,t,f;//num-分割方式 tmp-临时分割 len-分割组数 mm-最大分割和 f-判多解(rejected) int getlen(int x)//求x位数对应的10^n 用以dfs时取余(分割) { int cnt = 1; while(x) { x /= 10; cnt *= 10; } return cnt/10; } void dfs(int rest,int sum,int site,int l,int p)//p 0无前导零 1有前导 { if(sum + rest <= t && sum + rest >= mm) { if(sum + rest == mm || p == 1)//满足条件时多解或某组有前导零 { f = 1; mm = sum + rest; return; } f = 0; mm = sum + rest; memcpy(num,tmp,sizeof(tmp)); num[site++] = rest; len = site; return; } if(sum + rest < t && sum + rest < mm) return;//当前已小 后继更小 for(int i = l; i >= 1; i /= 10) { tmp[site] = rest/i; if(i > 10 && rest%i/(i/10) == 0) dfs(rest%i, sum + rest/i, site+1, i/100,1);//判分割后余下的数是否有前导零 else dfs(rest%i, sum + rest/i, site+1, i/10,p); } } int main() { int n; while(~scanf("%d %d",&t,&n) && (t+n)) { f = 0; len = 0; mm = -1; dfs(n,0,0,getlen(n),0); if(mm == -1) puts("error"); else if(f) puts("rejected"); else { printf("%d",mm); for(int i = 0; i < len; ++i) printf(" %d",num[i]); puts(""); } } return 0; }
自己的待修改答案:
#include <iostream> #include <vector> using namespace std; unsigned int close_tar;//距离给定目标的距离 bool objected; vector<int> digits; vector<int> close_digits; unsigned int target, number; bool pref_zero=false;//前导0 //一个数的各位数字之和 int sum_of_digits(int num) { int sum=0; while(num){ sum += num%10; num /= 10; } return sum; } //大于num的最小10的幂 int maxpower_of_digits(int num) { int power = 10; while(num/power){ power *= 10; } return power; } //数字的长度 int len_of_num(int num) { int len=0; int power=10; while(num){ len++; num /= 10; } return len; } //从左到右计算num中'0'的索引,从1开始,反序排列 vector<int> index_zero(int num) { int i=0; int len_num=len_of_num(num); int power = 10; vector<int> index; while(num) { if (num%10 == 0) { index.push_back(len_num-i); } num /= 10; i++; } return index; } //添加数字中丢失的零 vector<int> addzero(const int n,vector<int> not_zero, bool& inter_zero) { vector<int> zeroindex = index_zero(number); if (zeroindex.empty()){ return not_zero; } vector<int> add_zero; int prelen=0; for (vector<int>::iterator i=not_zero.begin(); i<not_zero.end(); i++) { prelen+=len_of_num(*i); while(prelen>=zeroindex.back()) { add_zero.push_back(0); inter_zero=true;//数据含有前导0 zeroindex.pop_back(); if (zeroindex.empty()){ break; } prelen++; } add_zero.push_back(*i); } while(!zeroindex.empty()) { add_zero.push_back(0); zeroindex.pop_back(); } return add_zero; } void dps(int num, unsigned int tar) { if (num==0) //数字已经用完,结束 { //专门写段补0的程序,并判断时候有前导0 close_digits = addzero(number, digits, pref_zero); if (tar == close_tar || pref_zero) { //两次出现最小数或数据中间有0 objected = true; } else if(close_tar > tar) { close_tar = tar; objected = false; } return; } for (int i=1; i<maxpower_of_digits(num); i*=10) { int pref = num/i; int suf = num%i; int newtar = tar-pref; if (newtar>=0){ digits.push_back(pref); dps(suf, newtar); digits.pop_back(); } } } int main() { cin >> target >> number; while(target || number) { if (target == number){ cout << number << ' ' << number << endl; } else if (sum_of_digits(number) > target) { cout << "error" << endl; } else { close_tar = target; objected = false; pref_zero=false; digits.clear(); close_digits.clear(); dps(number, target); if (objected==true){ cout << "objected" << endl; } else { cout << target-close_tar; for (int i=0; i<close_digits.size(); i++) { cout << ' ' << close_digits.at(i); } cout << endl; } } cin >> target >> number; } return 0; }
相关文章推荐
- JavaScript ES6新的类继承特性学习笔记
- 商品信息系统改名称
- 用Chrome来调试你的Android应用
- 线性时间排序
- shell脚本相关知识
- java JTable 列自适应大小(平均分配)
- HDFS 2.x HA机制
- 将二进制转换为十进制
- mongodb 安装配制
- windows不能在本地计算机上运行oracleDbConsoleorcl
- 1.05.体验-Cisco UC-基本功能 v1.1(请-下载-附件(百度云盘)! 有惊喜!)
- leetcode 172 Factorial Trailing Zeroes
- 第16周程序阅读(3)
- 深入学习Activity 之intent的匹配规则
- POJ 2420 A Star not a Tree? (模拟退火)
- ACM:蓝桥杯:小明的存钱计划
- Applet再学习
- 导入sql时报日期类型错误
- 【剑指offer】打印1到最大的n位数
- 《一步一步嵌入式操作系统》笔记2-环境搭建