问题 N: 我有一个梦想

题目描述

「Tweetuzki 你怎么这么菜啊,打了这么久 CF 还没紫。」
「Emmm…」
「Tweetuzki 你好菜啊,怎么打个 Div2 都能掉分的啊。」
「Emmm…」
「Tweetuzki 你不行啊,这不是傻逼题你怎么没秒啊?」
「Emmm…」
「Tweetuzki,等会有一场 Div2,你赶紧上紫啊。」
「我……尽力吧」
微弱的灯光在漆黑的夜晚里,闪烁得如此明亮。凌乱的英文字母与纷杂的几何图形无序地洒在屏幕上,照映在冥思苦想的 Tweetuzki 的脸庞上。
这是一道很简单的题,样例都通过了,但是没法通过测试数据。枯燥的 Debug 换来的只是一句话 Wrong Answer on Pretest 2。
「我究竟错在哪了……」
寂静的深夜,无助的哭喊。无人应答。
CF-Predictor 早早显示出掉 rating 的标记,随着时间的侵蚀而不断变大。秒针的每一次移动,都如同扎在 Tweetuzki 的心上一般,心痛,却又无可奈何。
「难道我真的像学长说的一样,那么菜,永远上不了紫名吗……」
泪水夺眶而出。
眼前的世界逐渐模糊,又逐渐清晰起来。这回 Tweetuzki 看分明了,是两个数字,两个关键的数字
「天哪!原来还有他们!」
如梦初醒。
Pretests Passed.
Accepted.
Tweetuzki → Tweetuzki.
Tweetuzki 把这道有纪念意义的题目搬过来了。Tweetuzki 希望这道题的 100 分,能够给在排行榜上争一的你,提供一个有力的援助。
你得到了一个边长为 2n 的正方形。每次操作你可以选择一个边长不为 1 的正方形,将这个正方形十字切开,分成四个完全相同的小正方形。
你需要进行恰好 k 次操作。k 次操作后会形成一种局面。我们称一种局面是合法的,当且仅当存在一条从左下角的正方形到右上角的正方形,所有正方形长度相等的路径。
请你判断是否存在一种合法局面。如果存在,你还需要找出所有操作可以形成的所有合法局面中,路径上正方形边长的最小值。
「学长学长,我终于紫名了!」
「Tweetuzki 你怎么才紫名啊,你好菜啊。」

输入

第一行输入一个正整数t(1≤t≤103),表示数据组数。
接下来t行,每行输入两个正整数n,k(1≤n≤109;1≤k≤1018),意义如题目所述。

输出

输出t行,每行输出该组数据的答案。
若k次操作后能找出路径,输出Yes和路径上正方形的最小边长。因为这个边长可能很大,请输出这个边长取关于2的对数(即若答案为2x,输出这个x的值即可)。
若无解,输出No。

样例输入
复制样例数据 3
1 1
2 2
2 12

样例输出
Yes 0
Yes 1
No

思路:这道题首先判断k是否比能切割的数目要大,若大则输出“No“,否则就按最优的方案切割

最优方案:对左边界及上边界的所有方块进行切割,画图后可知切割的次数为1,3,7,15(每个数为前一个数的2倍加1),判断k是否大于按最优方案切割的总次数,若是n–,最后输出n即可

但是这道题有一个坑:就是n== 2 , k==3时也是不可以的;(这就是题目提示的两个关键的数字)

typedef long long ll;
const ll maxn=1e18;
ll bit4[200];
int cnt=1;
void ini()
{
    ll i;
    for(i=4;i;i*=4)
    {
        bit4[cnt++]=(i-1)/3;
        if(bit4[cnt-1]>maxn) break;
    }

}

int main()
{
    ini();
    int T;cin>>T;
    while(T--)
    {
        int n;ll k;
        cin>>n>>k;
        ll Cnt=1,sum=1;
        if(n<=31&&k>bit4[n]||(n==2&&k==3)) {cout<<"No"<<endl; continue;}///n==2,k==3要特判
        while(k>=sum&&n>0)
        {
            Cnt=Cnt*2+1;
            sum+=Cnt;
            n--;
        }
        cout<<"Yes"<<' '<<n<<endl;
    }
}
发布了95 篇原创文章 · 获赞 7 · 访问量 8469

猜你喜欢

转载自blog.csdn.net/Spidy_harker/article/details/98175013