• 老司机的奇怪noip模拟T2-huangyueying


    2. 黄月英
    (huangyueying.cpp/c/pas )
    【问题描述】
    xpp 每天研究天文学研究哲学,对于人生又有一些我们完全无法理解的思考。
    在某天无聊学术之后, xpp 打开了 http://web.sanguosha.com, 准备用他心爱的黄月英
    虐人。进入了八人身份局,作为一位主公,xpp 果断选了黄月英,用黄月英挑 7 人。
    xpp 为什么喜欢黄月英这个武将呢?因为集智是个很牛逼的技能。
    集智——每当你使用一张非延时类锦囊(在它结算之前)你可以立即摸一张牌。
    可见集智这个技能如果用得好那么牌是摸不完的。于是 xpp 把 7 个人全部轻松干掉。
    虽然 xpp 的集智永远都能摸锦囊, 但是他想到了这样一个问题: 由于黄月英是一个富有
    智慧的人,所以 xpp 也要想一个富有智慧的问题,具体说来,他对牌上的数字产生了兴趣,
    于是他想知道,牌上每个数字出现过多少次。
    当然,要算牌上的数字太简单了。所以 xpp 要扩大范围。
    xpp 正在考虑这样一个问题:从一个数字 a 到另一个数字 b 之间,从 0 到 9 的每个数字
    出现过多少次。
    xpp 智商过于强大,不屑于想此等低端问题,然后你就要把这道题做出来。
    【输入】
    输入文件名为 huangyueying.in。
    共一行,每行两个整数,分别为 a,b。
    【输出】
    输出文件名为 huangyueying.out。
    输出共一行,包含 10 个整数,分别代表从 0 到 9 的数字各出现过多少次。
    【输入输出样例】
    huangyueying.in

    24 69 

    huangyueying.out


    4 4 10 14 15 15 15 5 5 5
    【数据范围】
    对于 30%的数据,a≤b≤1000000。
    对于 100%的数据,a≤b≤10^12。

     ————————————————题解

    一道极为水的数位dp,但我一直没调出来

    原先统计的时候没有统计前缀0,单纯算每个数,觉得去前导0太麻烦,然后就再也调不通了,后来看题解发现其实去的话也不是那么麻烦……然后就过了

    【老司机的数据十分坑】

    就是我们算4997,我们加上000-999(搞掉前缀0),加上1000-1999,加上2000-2999,加上3000-3999,加上998个4,然后我们再搞下一位……第一位4我们可以扔掉不管

    正确性写个暴力对拍就知道了

      1 #include <iostream>
      2 #include <string.h>
      3 #include <cstdlib>
      4 #include <cstdio>
      5 #include <algorithm>
      6 #include <cstring>
      7 #include <vector>
      8 #include <ctime>
      9 #define ivorysi
     10 #define mo 10007
     11 #define siji(i,x,y) for(int i=(x);i<=(y);i++)
     12 #define gongzi(j,x,y) for(int j=(x);j>=(y);j--)
     13 #define xiaosiji(i,x,y) for(int i=(x);i<(y);i++)
     14 #define sigongzi(j,x,y) for(int j=(x);j>(y);j--)
     15 #define ivory(i,x) for(int i=head[x];i;i=edge[i].next)
     16 #define pii pair<int,int>
     17 #define fi first
     18 #define se second
     19 #define inf 10000000
     20 using namespace std;
     21 typedef long long ll;
     22 ll dp[15][15][15];//dp(i,j,k)i位数,j开头,k的个数
     23 ll num[12]={//为啥我sb到打了这个表
     24     0,
     25     10,
     26     100,
     27     1000,
     28     10000,
     29     100000,
     30     1000000,
     31     10000000,
     32     100000000,
     33     1000000000LL,
     34     10000000000LL,
     35     100000000000LL
     36 };
     37 void init() {
     38     siji(i,0,9) {
     39         dp[1][i][i]=1;
     40     }
     41     siji(i,2,12) {
     42         siji(j,0,9) {
     43             siji(k,0,9) {
     44                 siji(h,0,9) {
     45                     dp[i][j][k]+=dp[i-1][h][k];
     46                 }
     47             }
     48             dp[i][j][j]+=num[i-1];
     49         }
     50     }
     51     siji(i,1,12) {
     52         siji(j,1,9) {
     53             siji(k,0,9) {
     54                 dp[i][j][k]+=dp[i][j-1][k];
     55             }
     56         }
     57     }
     58 }
     59 ll a,b;
     60 ll ansa[15],ansb[15];
     61 void query(ll c,ll *arr) {
     62     if(c==-1) return ;
     63     ll tmp=c;
     64     int len=0,x[15];
     65     while(tmp) {
     66         x[++len]=tmp%10;
     67         tmp/=10;
     68     }
     69     gongzi(i,len,2) {
     70         if(x[i]!=0) {
     71             siji(k,0,9){
     72                 arr[k]+=dp[i-1][9][k];
     73             }
     74             if(i==len) siji(k,1,i-2) arr[0]-=num[k];
     75             /*
     76                 假如我们做的是000-999
     77                 我们要搞掉000-009两次0
     78                 搞掉010-099一次0
     79                 这要合起来我们搞一遍000-099一次0(100个0)
     80                 搞000-009一次0(10个0)
     81             */
     82             if(i!=len)arr[0]+=num[i-1];
     83         }
     84         xiaosiji(p,1,x[i]) {
     85             siji(k,0,9) {
     86                 arr[k]+=dp[i-1][9][k];
     87             }
     88             arr[p]+=num[i-1];
     89         }
     90         arr[x[i]]+=c%num[i-1]+1;//加上这一位后面数
     91     }
     92     siji(i,0,x[1]) ++arr[i];
     93 }
     94 int main() {
     95 #ifdef ivorysi
     96     freopen("huangyueying.in","r",stdin);
     97     freopen("huangyueying.out","w",stdout);
     98 #else 
     99     freopen("f1.in","r",stdin);
    100 #endif
    101     scanf("%I64d%I64d",&a,&b);
    102     init();
    103     query(a-1,ansa);
    104     query(b,ansb);
    105     siji(i,0,9) {
    106         printf("%I64d%c",ansb[i]-ansa[i]," 
    "[i==9]);
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    GIL
    CRM2Stark组件
    Django图书管理系统(单表操作)
    Python(ATM机low版)
    Python(9-18天总结)
    Python(1-8天总结)
    Python习题(分页显示)
    Python文本操作2
    Python递归二分法
    Python文本操作
  • 原文地址:https://www.cnblogs.com/ivorysi/p/5860675.html
Copyright © 2020-2023  润新知