| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
没用高精度 总结一下我的想法是用long long存储读入的N
从N的二进制低位到高位进行扫描,第i位的情况用N[i]表示,分以下几种情况讨论
1>如果string[i] == p, 将N[i]置为0,记下答案N[i]
2>如果string[i] == n, 将N这个数字加上一个数,这个数字的其他位都为0,只有第i位为1.记下答案N[i].
举个例子:
ppnn
10
10的二进制表示是1010, 从低位开始扫描。
1.N[0] == 0, string[i] == n, 记下答案0
2.N[1] == 1, string[i] == n, 记下答案1, 并且将N + 0010, N == 1100
3.N[2] == 1, string[i] == p, 记下答案1
4.N[3] == 1, string[i] == p, 记下答案1
如果最后N == 0则可以表示,否则impossible。最后输出是1110
这个很好证明, 如果一个负数位取1的话,如果还想继续表示N,肯定要把N变大,这样才能保证N == N'.
由于对于负数以上方案就不合适了,因为负数在计算机当中存的是补码,处理起来比较麻烦所以对负数进行优化:
如果是负数则变正数, string中n变p,p变n。
最后N可以用unsigned long long来保存,判断64位的情况可以用N + i < N来表示,如果溢出则impossible。
最后给出关键代码:
unsigned long long n;
scanf("%d %s %lld", &len, str, &temp);
if (temp < 0)
{
for (int i = 0; i < len; ++ i)
str[i] = str[i] == 'p' ? 'n' : 'p';
temp = -temp;
}
n = temp;
bool flag = true;
for (int stri = len - 1; stri >= 0; i <<= 1, -- stri)
{
ans[stri] = (n & i) == i;
if (str[stri] == 'n' && (n & i) == i)
{
if (n + i < n)
{
flag = false;
break;
}
n += i;
}
n &= (0xffffffffffffffff ^ i);
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator