zoukankan      html  css  js  c++  java
  • HDU 3271 SNIBB

    SNIBB

    Time Limit: 1000ms
    Memory Limit: 32768KB
    This problem will be judged on HDU. Original ID: 3271
    64-bit integer IO format: %I64d      Java class name: Main
     
      As we know, some numbers have interesting property. For example, any even number has the property that could be divided by 2. However, this is too simple. 
      One day our small HH finds some more interesting property of some numbers. He names it the “Special Numbers In Base B” (SNIBB). Small HH is very good at math, so he considers the numbers in Base B. In Base B, we could express any decimal numbers. Let’s define an expression which describe a number’s “SNIBB value”.(Note that all the “SNIBB value” is in Base 10)
      

        Here N is a non-negative integer; B is the value of Base.
      For example, the “SNIBB value” of “1023” in Base “2” is exactly:10
    (As we know (1111111111)2=(1023)(10))
      Now it is not so difficult to calculate the “SNIBB value” of the given N and B.
    But small HH thinks that must be tedious if we just calculate it. So small HH give us some challenge. He would like to tell you B, the “SNIBB value” of N , and he wants you to do two kinds of operation:
    1.  What is the number of numbers (whose “SNIBB value” is exactly M) in the range [A,B];
    2.  What it the k-th number whose “SNIBB value” is exactly M in the range [A,B]; (note that the first one is 1-th but not 0-th)

    Here M is given.
     

    Input

      There are no more than 30 cases.
      For each case, there is one integer Q,which indicates the mode of operation;
      If Q=1 then follows four integers X,Y,B,M, indicating the number is between X and Y, the value of base and the “SNIBB value”.
    (0<=X,Y<=2000000000,2<=B<=64,0<=M<=300)
      If Q=2 then follows five integers X,Y,B,M,K, the first four integer has the same meaning as above, K indicates small HH want to know the k-th number whose “SNIBB value” is exactly M.
    (1<=K<=1000000000)
     

    Output

      Output contains two lines for each cases.
      The first line is the case number, the format is exactly “Case x:”, here x stands for the case index (start from 1.).
      Then follows the answer.
      If Q=2 and there is no such number in the range, just output “Could not find the Number!” (without quote!) in a single line.
     

    Sample Input

    1 0 10 10 3
    2 0 10 10 1 2
    1 0 10 2 1

    Sample Output

    Case 1:
    1
    Case 2:
    10
    Case 3:
    4
    Hint
    In case 1, the number in the range [0,10] whose “SNIBB value” is exactly 3 is 3(in Base 10); In case 2, the numbers in the range [0,10] whose “SNIBB value” is exactly 1 are 1 and 10; Of course the 2-th number is 10. In case 3, the number in the range [0,10] whose “SNIBB value” is exactly 1 is 1,10,100,1000(in Base 2);

    Source

     
    解题:数位dp + 二分
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 using LL = long long;
     4 int dp[45][310],bit[45],op,x,y,b,m,k;
     5 int dfs(int len,int sum,bool flag){
     6     if(-1 == len) return sum == m;
     7     if(!flag && dp[len][sum] != -1) return dp[len][sum];
     8     int ret = 0,u = flag?bit[len]:(b - 1);
     9     for(int i = 0; i <= u; ++i)
    10         ret += dfs(len - 1,sum + i,flag && i == u);
    11     if(!flag) dp[len][sum] = ret;
    12     return ret;
    13 }
    14 int solve(int n){
    15     if(n <= 0) return n == m;
    16     int len = 0;
    17     while(n){
    18         bit[len++] = n%b;
    19         n /= b;
    20     }
    21     return dfs(len - 1,0,true);
    22 }
    23 int main(){
    24     int cs = 1;
    25     while(~scanf("%d%d%d%d%d",&op,&x,&y,&b,&m)){
    26         memset(dp,-1,sizeof dp);
    27         if(x > y) swap(x,y);
    28         int p = solve(x - 1),q = solve(y);
    29         printf("Case %d:
    ",cs++);
    30         if(op == 1) printf("%d
    ",q - p);
    31         else{
    32             scanf("%d",&k);
    33             if(q - p < k){
    34                 puts("Could not find the Number!");
    35                 continue;
    36             }
    37             int low = x,high = y,ans;
    38             while(low <= high){
    39                 int mid = (static_cast<LL>(low) + high)>>1;
    40                 if(solve(mid) - p >= k){
    41                     ans = mid;
    42                     high = mid - 1;
    43                 }else low = mid + 1;
    44             }
    45             printf("%d
    ",ans);
    46         }
    47     }
    48     return 0;
    49 }
    View Code
  • 相关阅读:
    Codeforces Round #693 (Div. 3) G. Moving to the Capital (图,dp)
    Educational Codeforces Round 102 (Rated for Div. 2) B. String LCM (构造,思维)
    Hadoop离线计算——环境搭建(一)
    大数据项目开发进度(实时更新)
    【迭代式开发】v1架构设计文档——大数据开发实战项目(三)
    【迭代式开发】V1软件需求规格说明书——大数据开发实战项目(二)
    Flume安装——环境搭建(二)
    【中英双语】Spark官方文档解读(一)——Spark概述
    TortoiseSVN使用教程【多图超详细】——大数据开发实习day1
    【深度学习TPU+Keras+Tensorflow+EfficientNetB7】kaggle竞赛 使用TPU对104种花朵进行分类 第十八次尝试 99.9%准确率
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4960349.html
Copyright © 2011-2022 走看看