1. 程式人生 > 其它 >P5657 [CSP-S2019] 格雷碼

P5657 [CSP-S2019] 格雷碼

連結:

P5657


分析:

簽到題,不過也有不少細節。

資料範圍需要開 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;
}
題外話:

籤道題罷了