正题
大意
将二进制从右到左的权值改为:
1,-2,4,-8,16,-32,64…
然后给出一个数用二进制表达出来,如:
−13=110111=1×(−32)+1×16+1×4+1×(−2)+1×1−13=110111=1×(−32)+1×16+1×4+1×(−2)+1×1
解题思路
注意:这不是最优解。
比赛的时候就一直在想用贪心,其实我们可以如果是负数的话就把所有的都反过来,然后每次乘以4,把所有的加起来直到大于输出的数,然后将多余的减去就好了。
假设多出2,那么我们就将(-2)给加上。假设多出4那么就减去4,以此类推
代码
#include<cstdio>
using namespace std;
int n,nn,w,ans,y;
long long k,s;
bool a[10001];
int main()
{scanf("%d",&n);if (n==0){printf("0");return 0;}if (n<0){k=2;//第一个负数nn=-n;w=2;//第一个负数的位置}else{ans=1;nn=n;k=1;//第一个正数w=1;//位置}while (s<nn){s+=k;k*=4;//下一个(负/正)数w+=2;//位数}k/=4;w-=2;y=w;for (long long i=k;i>=1;i/=2){a[w]=true;if (s-i>=nn){s-=i;if (w%2==ans)a[w]=false;}else if (w%2!=ans){a[w]=false;}w--;}//去除多余的for (int i=y;i>=1;i--)if (a[i]) printf("1");else printf("0");
}