Problem B
Power Signs
Input: Standard Input
Output: Standard Output
"Increase my killing power, eh?"
– Homer Simpson
–
You are probably familiar with the binary representation of integers, i.e. writing a nonnegative integer n as ∑ai2i, where each ai is either 0 or 1. In this problem, we consider a so called signed binary representation, in which we still write n as ∑ai2i, but allow ai to take on the values -1, 0 and 1. We write a signed binary representation of a number as a vector (ak, ak-1, ..., a1, a0). For instance, n = 13 can be represented as (1, 0, 0, -1, -1) = 24 - 21 - 20.
The binary representation of a number is unique, but obviously, the signed binary representation is not. In certain applications (e.g. cryptography), one seeks to write a number n in signed binary representation with as few non-zero digits as possible. For example, we consider the representation (1, 0, 0, -1) to be a better representation of n = 7 than (1, 1, 1). Your task is to write a program which will find such a minimal representation.
10000 1111 10111 0
|
+0000 +000- ++00-
|
Problem setter: Per Aurtrin
Special Thanks: Mikael Goldmann
让0减少的唯一方式,就是类似用+00-这样的形式替换111,还要注意连续的2个1,是否替换?如果2个1在开头,就不换,否则换,字典序会变小。
#include<cstdio> #include<map> #include<queue> #include<cstring> #include<iostream> using namespace std; const int maxn = 50000 + 5; typedef long long LL; typedef pair<int,int> P; char s[maxn]; void change(int last, int pos){ s[last] = '-'; for(int j = last-1;j > pos;j--){ s[j] = '0'; } s[pos] = '1'; } int main(){ while(scanf("%s", s+1)){ if(s[1] == '0') break; int n = strlen(s+1); s[0] = '0'; int pos = n; int sum = 0; int last = -1; while(pos >= 1){ if(s[pos]=='1'){ if(last == -1){ last = pos; } sum++; } else{ if(sum >= 2){ change(last, pos); sum = 1; last = pos; } else{ sum = 0; last = -1; } } pos--; } if(sum > 2){ change(last, pos); } for(int i = 0;i <= n;i++){ if(s[i]=='1') s[i] = '+'; } if(s[0]=='0') printf("%s\n",s+1); else printf("%s\n",s); } return 0; }