pku oj 1001 Exponentiation
2012-11-04 13:15
183 查看
#include <iostream> #include <string> #include <map> using namespace std; typedef map<int, string> map_power; //题目中0 < n <= 25 int GetMaxLessEqu(int n) { if (0 == (n & (n-1))) return n; int ret = 1; while (ret < n) ret<<=1; return ret>>1; } int GetInteger(string& str) { int radix = 0; const int pos = str.find('.'); if (string::npos != pos)//有小数点 { while ('0' == str[str.size()-1]) str.erase(str.size()-1, 1); str.erase(pos, 1); radix = str.size() - pos; } while ('0' == str[0]) str.erase(0, 1); return radix; } //C = A*B void mul(string& C, const string& A, const string& B) { int tail = A.size() + B.size()-1; C.resize(tail+1); C.assign(C.size(), 0); for (int i = B.length()-1; i >= 0; i--) { for (int j = A.length()-1; j >= 0; j--) { const int pos = tail - (A.length()-1-j) - (B.length()-1-i); const int ret = (B[i]-'0')*(A[j]-'0'); C[pos] += ret; C[pos-1] += C[pos]/10; C[pos] %= 10; } } for (int i = 0; i < C.size(); i++) C[i] += '0'; while ('0' == C[0]) C.erase(0, 1); } void output(string& str, int radix, int n) { if (radix > 0) { int i; radix *= n; int diff = (int)str.size() - radix; if (diff > 0) { for (i = 0; i < str.size()-radix; i++) cout<<str[i]; cout<<'.'; for (; i < str.size(); i++) cout<<str[i]; } else { cout<<'.'; for (i = 0; i < radix-str.size(); i++) cout<<'0'; for (i = 0; i < str.size(); i++) cout<<str[i]; } } else cout<<str; cout<<endl; } int main() { int n; string r; while (cin>>r>>n) { const int nBackup = n; string digit = r; int radix = GetInteger(digit); int maxLessEqu = GetMaxLessEqu(n); map_power powVal; powVal[1] = digit; string cur = digit, ret = digit; for (int i = 2; i <= maxLessEqu; i*=2) { mul(ret, cur, cur); powVal[i] = cur = ret; } if (maxLessEqu != n) { cur = powVal[maxLessEqu]; while (0 != n) { n -= maxLessEqu; if (0 == (n & (n-1)))//n为2的幂 { mul(ret, cur, powVal ); break; } else { mul(ret, cur, powVal[maxLessEqu/=2]); cur = ret; } } } output(ret, radix, nBackup); } return 0; }我主要的思路是先把输入的浮点数转成整形,并记下小数点的位置。mul函数用来计算两个整数的乘积,最后输出的时候再添加上小数点。这个题目是计算幂,比如x^n,普通方法是连续乘积n-1次,这里我采取的办法是n = 2^x1 + 2^x2 + ... + 2x^m。比如17 = 16 + 1,23 = 16 + 4 + 2 + 1。这样可以少做几次乘法。刚开始做OJ,水平和技巧还有待提高。代码有点长,但是逻辑上会清楚点。路漫漫其修远兮。
另外遇到的一个问题值得mark一下,我之前写了这么一句其中
if (str.size() - radix > 0){...}其中str为string类型,radix为int类型,str.size()为73,radix为80。结果能走进 if 里面,我好奇怪啊,都怀疑是不是编译器出错了。试了好半天,联想到编译时的"warning C4018: “<”: 有符号/无符号不匹配"。突然想到了,str.size()为size_t类型,radix为int类型,两者相减后的类型是较高的size_t,-7也就转成了size_t类型,成了正数,也就走进 if 了。
今天(12-11-06)看到三星笔试题里有一道,和我上面说的那个问题一个意思,只不过上面那个应该更隐晦一点。
void foo(void) { unsigned int a = 6; int b = -20; (a+b > 6) ? puts("> 6") : puts("<= 6"); }输出是> 6
相关文章推荐
- PKUOJ1017 Packets
- PKU OJ Exponentiation
- 期望-pku-oj-1055:Tree
- PKUOJ1163 The Triangle
- PKUOJ2250 Compromise
- 刘汝佳黑书 pku等oj题目
- PKUOJ1579 Function Run Fun
- PKUOJ1593 World Cup Noise
- pku oj overhang叠加卡片求最少的卡片数
- 期望-pku-oj-1055:Tree
- Pku oj 1004 Financial Management(水题)
- PKUOJ1458 Common Subsequence
- 卡特兰数应用 pku OJ ID:1095
- Pku oj 3617 Best Cow Line(贪心)
- 刘汝佳黑书 pku等oj题目[转]
- 刘汝佳黑书 pku等oj题目
- PKU OJ题目分类 + 背包算法
- PKUOJ1159 Palindrome
- PKUOJ1042 Gone Fishing
- 刘汝佳黑书 pku等oj题目