P5657 [CSP-S2019] 格雷碼
阿新 • • 發佈:2021-08-06
連結:
分析:
簽到題,不過也有不少細節。
資料範圍需要開 unsigned long long
,前年也有很多人因此丟了5分。
pow
會出現神必錯誤,需要手寫一個 mpow
函式。
演算法:
我是記錄當前的 \(l,r\) 判斷 \(k\) 與 \(mid\) 的大小,然後分類討論倒序和正序時選左邊和選右邊手玩的結論。變數 \(f\) 代表順序,0 代表正序,1 代表倒序。
\(k\) 在左邊時輸出 \(f\) 並令 \(f\) 等於 0,\(k\) 在右邊時輸出 \(1-f\) 並令 \(f\) 等於 1,然後二分下去即可。
但這樣做在 mid=(l+r)>>1
時可能爆 unsigned long long
mid=l/2+r/2+(l%2==1&&r%2==1);
。
程式碼:
#include<bits/stdc++.h> using namespace std; #define int unsigned long long int n,k; int qpow(int a,int b){ int ans=1llu; while(b){ if(b&1llu)ans=ans*a; a=a*a; b>>=1llu; } return ans; } signed main(){ cin>>n>>k; int l=0llu,r=qpow(2,n)-1llu,mid,f=0; while(l<r){ mid=l/2+r/2+(l%2==1&&r%2==1); if(k<=mid) cout<<f,f=0,r=mid; else cout<<1-f,f=1,l=mid+1; } return 0; }
題外話:
籤道題罷了