codeforces 489C.Given Length and Sum of Digits... 解题报告
2014-11-19 16:03
211 查看
题目链接:http://codeforces.com/problemset/problem/489/C
题目意思:给出 m 和 s,需要构造最大和最小的数。满足长度都为 m,每一位的数字之和等于 s。如果构造不出来,输出 -1 -1。否则输出最小和最大且符合条件的数。
想了两个多小时,发现想错了方向......
/******************************************
首先把不能得到最小数和最大数的情况揪出来。
第二组测试数据 3 0 有提示,s = 0 且 m > 1,
还有一种无解的情况就是 9 m < s(怎么填全部位的数字之和都凑不够 s),其实这种情况是有最小解的,前提是s >= 1,10000000....0 就是了,但是都归为 -1 -1 行列(感觉这个不是太过严谨)。
至于 s = 0,m = 1是 输出 0 0。然后就开始重头戏了........
我是从最小数开始构造的(感觉这样做就呵呵了),容易知道最小数的构造是,从个位开始填数,尽量填最大的数字9,然后剩下的数remain = s - 9,接着填十位、百位、......直到填完 第 m 位。我们要尽可能把最大的数字往低位填,那么才能保证最终得到的数是最小的。但是要考虑到填的过程中,有可能这个remain 不足9,然后尝试8,再不行的话,填7,直到0,不过前提是保证最高位最小为 1,保证没有前导 0 嘛。
但实现起来很复杂,循环是从 m-1 ——> 0 的,于是要考虑 i == 1 时,不能把remain完全填光,只能填remain + 1。对于第一组数据 2 15,ans:69 96;好像又要额外讨论......所以总体来讲,不好写,即使写出来也很烦琐。
******************************************/
看了别人的,一下子顿悟了!
从最大数开始构造就简单多了。循环变成 0 ~ m-1,然后死命填大数字9,不行的话填剩下最大的,之后的位就是填0了。
构造最小数更加方便,把最大数复制到最小数里,然后颠倒过来,如果首位是 0,就找到后面位中第一次遇到的非0数字,从它那里拿1,这位数就减1,就是答案了。
题目意思:给出 m 和 s,需要构造最大和最小的数。满足长度都为 m,每一位的数字之和等于 s。如果构造不出来,输出 -1 -1。否则输出最小和最大且符合条件的数。
想了两个多小时,发现想错了方向......
/******************************************
首先把不能得到最小数和最大数的情况揪出来。
第二组测试数据 3 0 有提示,s = 0 且 m > 1,
还有一种无解的情况就是 9 m < s(怎么填全部位的数字之和都凑不够 s),其实这种情况是有最小解的,前提是s >= 1,10000000....0 就是了,但是都归为 -1 -1 行列(感觉这个不是太过严谨)。
至于 s = 0,m = 1是 输出 0 0。然后就开始重头戏了........
我是从最小数开始构造的(感觉这样做就呵呵了),容易知道最小数的构造是,从个位开始填数,尽量填最大的数字9,然后剩下的数remain = s - 9,接着填十位、百位、......直到填完 第 m 位。我们要尽可能把最大的数字往低位填,那么才能保证最终得到的数是最小的。但是要考虑到填的过程中,有可能这个remain 不足9,然后尝试8,再不行的话,填7,直到0,不过前提是保证最高位最小为 1,保证没有前导 0 嘛。
但实现起来很复杂,循环是从 m-1 ——> 0 的,于是要考虑 i == 1 时,不能把remain完全填光,只能填remain + 1。对于第一组数据 2 15,ans:69 96;好像又要额外讨论......所以总体来讲,不好写,即使写出来也很烦琐。
******************************************/
看了别人的,一下子顿悟了!
从最大数开始构造就简单多了。循环变成 0 ~ m-1,然后死命填大数字9,不行的话填剩下最大的,之后的位就是填0了。
构造最小数更加方便,把最大数复制到最小数里,然后颠倒过来,如果首位是 0,就找到后面位中第一次遇到的非0数字,从它那里拿1,这位数就减1,就是答案了。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif int m, s; while (scanf("%d%d", &m, &s) != EOF) { if (m == 1 && s == 0) printf("0 0\n"); else if (s == 0 || 9*m < s) printf("-1 -1\n"); else { string s1, s2; for (int i = 0; i < m; i++) { int x = min(9, s); s -= x; s2 += char(x + '0'); } s1 = s2; reverse(s1.begin(), s1.end()); bool flag = false; for (int i = 0; i < m && !flag; i++) { if (s1[i] == '0') { for (int j = i+1; j < m && !flag; j++) { if (s1[j] != '0') { s1[j]--; s1[i]++; flag = true; break; } } } } cout << s1 << " " << s2 << endl; } } return 0; }
相关文章推荐
- HDOJ-1251-统计难题 解题报告
- leetcode解题报告233——Power of Two
- 【LeetCode】Merge Intervals 解题报告
- poj 3083 Children of the Candy Corn 解题报告-- DFS BFS
- UVa 769 - Magic of David Copperfield 解题报告(思维)
- LeetCode-Reverse Linked List-解题报告
- [Ahoi2014]奇怪的计算器 解题报告
- hoj Secret Message 解题报告
- UVa 165 - Stamps 解题报告(暴力)
- 【解题报告】Codeforces Round #354 (Div. 2)
- Pku acm 1125 Stockbroker Grapevine 数据结构题目解题报告(八)---- 弗洛伊德(floyd)算法
- Sicily 1350. Piggy banks 解题报告
- POJ1005解题报告
- HDU Common Subsequence 解题报告
- poj解题报告——3254
- [leetcode] 354. Russian Doll Envelopes 解题报告
- 【LeetCode】160.Intersection of Two Linked Lists(Easy)解题报告
- Pku acm 2371 Questions and answers 排序算法解题报告(三)----二叉查找数(BST)排序
- 杭电acm1019 hdu-acm-101解题报告
- 计蒜之道2016 遗失的支付宝密码 解题报告