• HDU 6156 Palindrome Function


     http://acm.hdu.edu.cn/showproblem.php?pid=6156

    题意:
    $f(n,k)$表示判断n在k进制下是否是回文串,如果是,则返回k,如果不是,则返回1。现在要计算$sum_{i=L}^{R}sum_{j=l}^{r}f(i,j)$。

    思路:
    因为我不会数位dp,所以我直接模拟做了一发,写得十分繁琐。。。

    先是将数转换成k进制,然后去计算出它的前一半的数,只要小于该数那都是成立的 ,比如说现在前面的数为985,那么1~984的数都是满足的,绝对不会超。

    思路大致就是这样,具体的话还有一些细节,请参见代码。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<sstream>
      6 #include<vector>
      7 #include<stack>
      8 #include<queue>
      9 #include<cmath>
     10 #include<map>
     11 #include<set>
     12 using namespace std;
     13 typedef long long ll;
     14 const int INF = 0x3f3f3f3f;
     15 const int maxn=50000+5;
     16 const int mod=1e9+7;
     17 
     18 ll L,R;
     19 int l,r;
     20 int dig[1000];
     21 
     22 ll solve(ll n, int k)
     23 {
     24     if(n==0)  return 0;
     25     int len=0;
     26     ll tmp=n;
     27     while(tmp)
     28     {
     29         dig[++len]=tmp%k;
     30         tmp/=k;
     31     }
     32     ll num=0;
     33     if(len&1)  //奇数位
     34     {
     35         if(len>=3)
     36         {
     37             ll base=1;
     38             for(int i=len/2+2;i<=len;i++)
     39             {
     40                 num+=dig[i]*base;
     41                 base*=k;
     42             }
     43             num--;   //除去本身,1~num-1的数都是可行的
     44             num*=k;  //奇位数的时候中间那位数可以自由选择
     45             base=1; ll tmp=0;
     46             for(int i=1;i<=len/2;i++)  //奇数位下偶数的情况,前面计算的都是奇位数的情况
     47             {
     48                 tmp+=(k-1)*base;  //直接算最大值即可
     49                 base*=k;
     50             }
     51             num+=tmp;
     52             num+=k-1;  //再加上一位数的情况,因为这个前面没有计算
     53         }
     54         else num=dig[1];
     55     }
     56     else   //偶数位
     57     {
     58         ll base=1;
     59         for(int i=len/2+1;i<=len;i++)
     60         {
     61             num+=dig[i]*base;
     62             base*=k;
     63         }
     64         num--;
     65         base=1; ll tmp=0;
     66         if(len>2)  //偶数位下奇位数的情况
     67         {
     68             for(int i=1;i<=len/2-1;i++)
     69             {
     70                 tmp+=(k-1)*base;
     71                 base*=k;
     72             }
     73             tmp*=k;
     74             num+=tmp;
     75         }
     76         num+=k-1;
     77     }
     78 
     79     ll cnt1=0,cnt2=0;
     80     //判断前一半的数和当前前一半数相等时的情况
     81     if(len&1)
     82     {
     83         if(len>=3)
     84         {
     85             ll base=1;
     86             int zero=0;
     87             for(int i=len;i>=len/2+2;i--)
     88             {
     89                 cnt1+=dig[i]*base;
     90                 if(dig[i]==0)  zero++;  //特别注意,排除前导0
     91                 if(zero==len-i+1)  continue;
     92                 base*=k;
     93             }
     94             base=1;
     95             for(int i=1;i<=len/2;i++)
     96             {
     97                 cnt2+=dig[i]*base;
     98                 base*=k;
     99             }
    100             int zhong=dig[len/2+1];
    101             if(cnt1<=cnt2)  num+=zhong+1;
    102             else num+=zhong;
    103         }
    104     }
    105     else
    106     {
    107         ll base=1;
    108         int zero=0;
    109         for(int i=len;i>=len/2+1;i--)
    110         {
    111             cnt1+=dig[i]*base;
    112             if(dig[i]==0)  zero++;
    113             if(zero==len-i+1)  continue;
    114             base*=k;
    115         }
    116         base=1;
    117         for(int i=1;i<=len/2;i++)
    118         {
    119             cnt2+=dig[i]*base;
    120             base*=k;
    121         }
    122         if(cnt1<=cnt2)  num++;
    123     }
    124     return k*num+(n-num);
    125 }
    126 
    127 int main()
    128 {
    129     //freopen("in.txt","r",stdin);
    130     int T;
    131     int kase=0;
    132     scanf("%d",&T);
    133     while(T--)
    134     {
    135         scanf("%lld%lld%d%d",&L,&R,&l,&r);
    136         ll ans=0;
    137         for(int k=l;k<=r;k++)
    138         {
    139             ans+=solve(R,k)-solve(L-1,k);
    140         }
    141         printf("Case #%d: %lld
    ",++kase,ans);
    142     }
    143     return 0;
    144 }
  • 相关阅读:
    系统分析师思维导图
    系统分析师案例分析知识点——虚拟内存篇
    系统分析师案例分析知识点——进程管理问题
    系统分析师案例分析知识点——进程同步问题
    200行代码实现RPC框架
    由vue3引起的一段值得记录经历
    PetaPoco在ASP.NET Core 2.2中使用注入方式访问数据库
    在.net core 中PetaPoco结合EntityFrameworkCore使用codefirst方法进行开发
    Quartz.NET的简单任务管理类
    System.Action的使用(lambda 表达式)
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7399476.html
Copyright © 2020-2023  润新知