• CF1080D Olya and magical square


    CF1080D Olya and magical square

    题目链接:CF1080

    这是一道很值得探究的数论找规律题(虽然大多数论都是找规律题)

    为了简化题目,我们将所走的路径都放到正方形的边缘上

    性质一:如果 $n>31$,那么我们可以对整个正方形切割一次,再对右下角的正方形随意切割,显然右下角的正方形的能够被切割的次数一定不小于 $10^{18}$

    因此当 $n>31$ 时直接输出 $YES$ 和 $n-1$ 即可!

    对于 $1leqslant n leqslant 31$ 的情况,我们枚举路径上的正方形的边长 $2^{i}$,计算出最少的切割次数 $L$ 和最多的切割次数 $R$,可以证明 $[L,R]$ 这个区间内的所有切割次数都可以被构造出来。

    如何计算最少的切割次数:考虑只切割出我们要走的路径的格子。每次只对边缘那一圈的格子切割,第一次需要切割 $1$ 次,第二次需要切割 $3$ 次,第三次需要切割 $7$ 次……

    因此最少的切割次数为 $sum_{j=1}^{n-i}2^j-1$.。 

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 int t;
     5 ll pw[35];
     6 int check (int n,ll k)
     7 {
     8     for (int i=0;i<n;i++)
     9     {
    10         int p=n-i;
    11         ll l=0;
    12         for (int j=1;j<=p;++j) l+=(1LL<<j)-1;
    13         if (l>k) continue;
    14         long long r=pw[n]-((1LL<<(p+1))-1)*pw[i];
    15         if (r<k) continue;
    16         return i;
    17     }
    18     return -1;
    19 }
    20 int main()
    21 {
    22     scanf ("%d",&t);
    23     for (int i=1;i<=32;++i) pw[i]=4LL*pw[i-1]+1;
    24     while (t--)
    25     {
    26         int n;
    27         long long k;
    28         scanf ("%d %lld",&n,&k);
    29         if (n>31) printf ("YES %d
    ",n-1);
    30         else
    31         {
    32             int    ans=check (n,k);
    33             if (ans<0) puts("NO");
    34             else printf("YES %d
    ",ans);
    35         }
    36     }
    37     return 0;
    38 }
  • 相关阅读:
    vue-router路由器的使用
    组件间数据传递
    引用模块和动态组件
    vue自定义全局和局部指令
    vue实例的属性和方法
    vue生命周期以及vue的计算属性
    vue 发送ajax请求
    安装vue-cli脚手架
    vue指令详解
    scrapy-redis组件的使用
  • 原文地址:https://www.cnblogs.com/PaulShi/p/10074782.html
Copyright © 2020-2023  润新知