原题链接 Problem - B - Codeforces
- 程序设计竞赛最中最重要的事情!!!读清楚题目!!!
- 题目的数据范围很小最多32位(标记二进制的数组需要开long long 不要会爆)
- 设计一个循环while(x) 当x==0的适合表示构造好了数组 退出循环
- 在循环过程中我们需要依次查找和abs(x-flag[i])绝对值最小,并且能够满足flag2[i]>=(abs(x-flag[i]的一个数
- 如果x当前的值要>0 那a[ans]=1否则 a[ans]=-1;
- 下面看代码可能会有更好的理解
-
#include<iostream> #include<cstring> #define ull long long using namespace std; const int n=50; ull a[n]; ull flag[n]; //用来标记0——位二进制数 ull flag2[n]; //用来标记当前i-1位前在没有连续非0的情况下,最大能表达的数是多少 void init() //初始化 { flag[0]=1; ull ans=2; for(int i=1;i<=32;i++) { flag[i]=ans; ans*=2; } int k; for(int i=32;i>=1;i--) { for(k=i-2;k>=0;k-=2) { flag2[i]+=flag[k]; } } } int find(ull x,int k) { ull maxv=1e10; int ans=0; x=abs(x); for(int i=32;i>=0;i--) { if((abs(x-flag[i])<maxv)&&(flag2[i]>=(abs(x-flag[i])))) { ans=i; maxv=abs(flag[i]-x); } } return ans; } void solve() { memset(a,0,sizeof(a)); int ans=-10; int k=0; int maxans=0; int x;cin >> x; while(x) { ans=find(x,ans); //其实这个可以不传的,没改了 if(x>0) { a[ans]=1; x-=flag[ans];} else { a[ans]=-1;x+=flag[ans];} maxans=max(ans,maxans); //记录最高位 } cout << maxans+1 << endl; for(int i=0;i<maxans;i++) { cout << a[i] << ' '; } cout << a[maxans]; //测试样最后一个数是没有空格的 cout << endl; } int main() { int t; init(); cin >> t; while(t--) { solve(); } }
有不懂的地方可以在下方留言,和博主交流哦
生命不息,奋斗不止,至每一位有目标的ACMer们:
“追风赶月莫停留 平芜尽处是春山”,本次div2 你们可能有所收获,也许有所遗憾。但是成功不自满,失败不气馁是每一位ACMer在经过无数次WA后磨练出来的坚强意志。在错误中吸取教训,继续前行,每一场比赛都是你通向成功的一步台阶。
当我们站在领奖台下,我们会遗憾,会惆怅,但是不要忘记你成为ACMer时的梦想。
致谢湘南ACMer