zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    统计MySQL数据库硬盘占用量大小
    zookeeper 集群安装与配置
    On Java 8中文版 英雄召集令
    下划线参数转成驼峰
    在Ubuntu 18.04中安装JDK 8
    GIT和GitHub的使用总结
    Python目录
    selenium代码实例
    Fiddler请求图标含义
    Tensorflow之神经网络
  • 原文地址:https://www.cnblogs.com/PaulShi/p/10074782.html
Copyright © 2011-2022 走看看