Codeforces Round #524 (Div. 2) Olya and magical square CodeForces - 1080D
阿新 • • 發佈:2018-12-15
題意:
給你 2^n * 2^n 的正方形,讓你執行恰好 k 次操作,每一次操作將一個大小不為 1 的正方形剪成四個一模一樣的正方形,但是正方形不能被移動。
問:k 次操作後,能否從左下角找一條路徑到達右上角(只能橫著或豎著走),使得經過的正方形大小相同(包含起點與終點)。
如果可以,輸出經過的正方形的邊長的以 2 為底的對數。
列舉路徑上正方形的邊長,判斷是否合法。
#include<stdio.h> #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<string.h> #include<queue> #include<stack> #include<list> #include<map> #include<set> #include<vector> using namespace std; typedef long long int ll; const int maxn =1e9+5; const int maxm=10000; const int mod =1e9+7; const int INF=0x3f3f3f3f; const double eps=1e-8; ll fpow(ll a,ll b) { ll ans=1; while(b) { if(b&1)ans=ans*a; a=a*a; b>>=1; } return ans; } int main() { int t;scanf("%d",&t); while(t--) { ll n,k;scanf("%lld%lld",&n,&k); if(n==2&&k==3) printf("NO\n"); else if(n>31) printf("YES %lld\n",n-1ll); else{ ll a=2; int flag=0; for(ll i=1;i<=n;i++){ ll len=n-i; ll p=a*a-a*2ll+1ll; ll k1=(fpow(4ll,i)-1ll)/3ll; ll k2=(fpow(4ll,len)-1ll)/3ll; if(k<=k1+k2*p){ flag=1; printf("YES %lld\n",len); break; } a*=2ll; } if(flag==0) printf("NO\n"); } } return 0; }