| ||||||||||
| 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 | |||||||||
依据表达范围求解 0ms依据:
1. n位长度的串表达2^n种值
e.g. 2位np 能表达 0, 1, -2, -1这4个值
2.这2^n个值是连续变化的
e.g. 2位np 能表达的值(0, 1, -2, -1)一定在[-2, 1]中, 且填满这个区间
3.基于上述两点,在表达范围内的值一定有唯一表达,不再范围内的值一定无法表达。
#include <cstdio>
#include <cstring>
#define MAXN (65)
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
#define abs(x) (((x)>0)?(x):(-(x)))
using namespace std;
int n;
long long v;
struct Digit{
unsigned long long v, mx, mi; //v记录该位的值,mx为从0位开始到该位能表达的上限,mi为下限
//都用unsigned记录,因为v的符号由s决定,mx只能是非负数,mi只能是非正数
char s; //记录该位的符号
}ds[MAXN];
int res[MAXN];
int main(){
char str[MAXN];
int tot;
scanf("%d", &tot);
while(tot--){
scanf("%d%s%lld", &n, str, &v);
memset(ds, 0, sizeof(ds));
for(int i = 0; i < n; i++){//按定义获得每一位的v, mx, mi
ds[i].s = str[n - i - 1];
ds[i].v = 1LL<<i;
if(i == 0){
if(ds[i].s == 'p') ds[i].mx = ds[i].v;
else ds[i].mi = ds[i].v;
continue;
}
ds[i].mx = ds[i - 1].mx;
ds[i].mi = ds[i - 1].mi;
if(ds[i].s == 'p') ds[i].mx += ds[i].v;
else ds[i].mi += ds[i].v;
}
//如何要表达的值不在表示范围内,则一定无法表达
if((v > 0 && ds[n - 1].mx < v) || (v < 0 && ds[n - 1].mi < abs(v))){
printf("Impossible\n");
continue;
}
//在范围内,一定有唯一表达
//从最高位开始,当第i位无法表达单前值时,i + 1位一定被设置为1,因此选中i+1,并更新当前值
memset(res, 0, sizeof(res));
int idx = n - 1;
while(v){
if(v > 0) for(; idx >= 0; idx--) if(ds[idx].mx < v) break;
else for(; idx >= 0; idx--) if(ds[idx].mi < abs(v)) break;
idx++;
res[idx] = 1;
if(ds[idx].s == 'p') v -= ds[idx].v;
else v += ds[idx].v;
}
for(int i = n - 1; i >= 0; i--) printf("%d", res[i]);
printf("\n");
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator