POJ 1906 Three Powers
2009-11-28 11:20
274 查看
Three powers
Description
Consider the set of all non-negative integer powers of 3.
S = { 1, 3, 9, 27, 81, ... }
Consider the sequence of all subsets of S ordered by the value of the sum of their elements. The question is simple: find the set at the n-th position in the sequence and print it in increasing order of its elements.
Input
Each line of input contains a number n, which is a positive integer with no more than 19 digits. The last line of input contains 0 and it should not be processed.
Output
For each line of input, output a single line displaying the n-th set as described above, in the format used in the sample output.
Sample Input
Sample Output
Source
Waterloo local 2004.06.12
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 3299 | Accepted: 1405 |
Consider the set of all non-negative integer powers of 3.
S = { 1, 3, 9, 27, 81, ... }
Consider the sequence of all subsets of S ordered by the value of the sum of their elements. The question is simple: find the set at the n-th position in the sequence and print it in increasing order of its elements.
Input
Each line of input contains a number n, which is a positive integer with no more than 19 digits. The last line of input contains 0 and it should not be processed.
Output
For each line of input, output a single line displaying the n-th set as described above, in the format used in the sample output.
Sample Input
1 7 14 783 1125900981634049 0
Sample Output
{ } { 3, 9 } { 1, 9, 27 } { 3, 9, 27, 6561, 19683 } { 59049, 3486784401, 205891132094649, 717897987691852588770249 }
Source
Waterloo local 2004.06.12
/* 终于用到了自己写的大数运算工具,呵呵,很兴奋啊,需要的可以去我的资源里下载 思路主要是: (1)对于数列{空, 1, 3, 9, 27, 81, ...}一直到3 ^ 64, 先分别利用大数工具计算出num3[i], exp3[i] exp3[i]就是数列3 ^ i, num3[i] = 2 ^ i,表示以 1 - i个数可以组成的子集合的个数 (2)对于输入val从第一位往高位寻找, 直到num3[pos] >= val, 则这个pos表示1-pos位的某个子集可以组 成第val个集合 (3)接下来需要判断1-pos位中那几位是在目标集合中的。从pos往低位处理,假设当前处理到了第p位 则如果val > num3[p - 1],则表示集合的构成离不开p,所以将exp3[p]加入目标集合中,同时val -= num3[p - 1]; 然后p--,往下处理 (4)最后输出结果即可 注意的是空集,也就是val = 1需要单独处理 */ #include <iostream> #include <cmath> #include <string> #define MAX_L 64 using namespace std; string exp3[MAX_L + 1]; string num3[MAX_L + 1]; int res[MAX_L + 1], len; /* 以下是我写的大数运算工具,需要全套工具的可以去我的资源里面下载 */ /** * This function return a reverse string for a given string * Modifer1: 2009.06.13 Finish the first edition of getReverse */ string getReverse(string str) { string revStr = ""; int pos = static_cast<int>(str.length()) - 1; for(; pos >= 0; pos--) revStr += str[pos]; return revStr; } /*大数比较*/ int bigIntegerCmp(string left, string right) { int lenl = static_cast<int>(left.length()); int lenr = static_cast<int>(right.length()); if(lenl < lenr) return -1; else if(lenl > lenr) return 1; return strcmp(getReverse(left).c_str(), getReverse(right).c_str()); } /*大数乘法*/ string bigIntegerMult(string left, string right) { int minLen = static_cast<int>(left.length()); int maxLen = static_cast<int>(right.length()); string longerStr = ""; string shorterStr = ""; string res = ""; //get the longer and short strings and corresponded length if(left.length() <= right.length()) { minLen = static_cast<int>(left.length()); maxLen = static_cast<int>(right.length()); shorterStr = left; longerStr = right; } else { minLen = static_cast<int>(right.length()); maxLen = static_cast<int>(left.length()); shorterStr = right; longerStr = left; } int pos1 = 0; int pos2 = 0; //start from the first digit of the shorter string for(pos1 = 0; pos1 <= minLen - 1; pos1++) { //multiply each digit of the longer string int residue = 0, product = 0, quotient = 0; int curPos = 0; for(pos2 = 0; pos2 <= maxLen - 1; pos2++) { curPos = pos1 + pos2; //new space if(res.length() == 0 || curPos > int(res.length() - 1)) { product = (shorterStr[pos1] - '0') * (longerStr[pos2] - '0') + quotient; quotient = product / 10; residue = product % 10; res += residue + '0'; } //space already exists, just add the original value to product else { product = (shorterStr[pos1] - '0') * (longerStr[pos2] - '0') + quotient + (res[curPos] - '0'); quotient = product / 10; residue = product % 10; res[curPos] = residue + '0'; } } //process the extra quotient //start position curPos = maxLen + pos1; while(quotient != 0) { if(res.length() == 0 || curPos > int(res.length() - 1)) { residue = quotient % 10; quotient = quotient / 10; res += residue + '0'; } else { quotient = quotient + (res[curPos] - '0'); residue = quotient % 10; quotient = quotient / 10; res[curPos] = residue + '0'; } curPos++; } } //std::cout<<res.length()<<std::endl; return res; } /*大数减法*/ string bigIntegerSub(string left, string right) { string biggerStr = ""; string smallerStr = ""; string res = ""; int minLen = 0; int maxLen = 0; //get the bigger integer and smaller integer int cmpRes = bigIntegerCmp(left, right); if(cmpRes == -1 || cmpRes == 0) { smallerStr = left; biggerStr = right; } else { smallerStr = right; biggerStr = left; } //get related size minLen = static_cast<int>(smallerStr.length()); maxLen = static_cast<int>(biggerStr.length()); int extra = 0, temp = 0, subRes = 0; //subtraction operation, first part int pos1; for(pos1 = 0; pos1 <= minLen - 1; pos1++) { int curL = biggerStr[pos1] - '0'; int curR = smallerStr[pos1] - '0'; temp = 0; while((subRes = (curL - curR + 10 * temp - extra)) < 0) temp++; res += subRes + '0'; extra = temp; } //subtraction operation, second part for(int pos2 = pos1; pos2 <= maxLen - 1; pos2 ++) { int curL = biggerStr[pos2] - '0'; temp = 0; while((subRes = (curL + 10 * temp - extra)) < 0) temp++; res += subRes + '0'; extra = temp; } //remove the zero at head while(res[res.length() - 1] == '0' && res.length() >= 2) res = res.substr(0, res.length() - 1); //std::cout<<"res size:"<<res.length()<<std::endl; return res; } int main() { int i; exp3[1] = "1"; num3[0] = "1"; for(i = 1; i <= MAX_L; i++) { if(i != 1) exp3[i] = bigIntegerMult(exp3[i - 1], "3"); num3[i] = bigIntegerMult(num3[i - 1], "2"); //cout<<num3[i]<<endl; } string val; while(cin>>val && val != "0") { len = 0; int pos = 0; if(val != "1") { val = getReverse(val); //寻找pos使得num3[pos] >= val while(bigIntegerCmp(num3[pos], val) < 0) pos++; //从pos往下处理,寻找目标集合的元素 while(bigIntegerCmp(val, "0") != 0 && pos > 0) { if(bigIntegerCmp(val, num3[pos - 1]) > 0) { res[len++] = pos; val = bigIntegerSub(val, num3[pos - 1]); } pos--; } cout<<"{"; for(pos = len - 1; pos >= 0; pos--) { cout<<" "; cout<<getReverse(exp3[res[pos]]); if(pos != 0) cout<<","; } cout<<" }"<<endl; }//空集需要单独处理 else cout<<"{ }"<<endl; } return 0; }
相关文章推荐
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- POJ 1906
- poj1906解题报告
- POJ 1906 数学题
- poj 1906
- POJ2407 ZOJ1906 UVA10229 Relatives【欧拉函数+数论】