zoukankan      html  css  js  c++  java
  • BZOJ 1026 windy数

         据说这是道数位dp的题,第一反应看到之后也觉得不难,大致思路马上就有了。(其实后来我所看的题解有一个和我想的也差不多,只不过好像觉得那样写太麻烦了,就不想写了,就开始和正道偏离了,所以有了思路之后一定要勇于尝试。)一开始是这样的,先处理出一个数组 f[i][j] 表示 第 i 位为 j 开头的符合题意的数有多少个。(经过这道题,也渐渐总结了一些经验,一开始思考不全面,没有处理好0的情况,所以以后一定要思考全面,把细节都想得差不多了再动手,否则后果真的……)。接下来,就因为0的问题,整个人乱掉了。后来就改成写搜索,然后TLE了(刚刚看了一下别人的题解,如果把爆搜改成记忆化搜索也是能过的,其实我也试着改了,以WA告终)。最后……。

           好吧,这是搜索的代码。其实和我写的差不多(我是指思路上,但是这份代码比我一开始写的简洁多了)。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define rep(i,j,k) for(int i = j; i <= k; i++)
     5 using namespace std;
     6 int num[12] = {0}, dp[100][100] = {0};
     7 
     8 int abs(int x,int y)
     9 {
    10     if( x > y )  return x - y; else return y - x;
    11 }
    12 int dfs(int po,int last,int ok,int first)
    13 {
    14     if( po == 0 ) return 1;
    15     if( !first && ok ){
    16         if( dp[po][last] != -1 ) return dp[po][last]; //记搜优化
    17     }
    18     int cur = first? num[po] : 9; // 这里写的很好。
    19     int ans = 0;
    20     if( ok ){
    21         rep(i,0,cur){
    22             if( abs(last,i) >= 2 ) ans += dfs(po-1,i,ok,first&&i==cur);  // 这里写的很好。
    23         }
    24     }
    25     else {
    26         rep(i,0,cur){
    27             ans += dfs(po-1,i,i,first&&i==cur);
    28         }
    29     }
    30     if( !first && ok ) {
    31         return dp[po][last] = ans; // 记搜优化
    32     }
    33     return ans;
    34 }
    35 
    36 int dpa(int n)
    37 {
    38     int tot = 0;
    39     while( n ){
    40         num[++tot] = n % 10;
    41         n /= 10;
    42     }
    43     return dfs(tot,0,0,1);
    44 }
    45 
    46 int main()
    47 {
    48     memset(dp,-1,sizeof(dp));
    49     int n, m; scanf("%d %d",&n,&m);
    50     cout<<dpa(m)-dpa(n-1)<<endl;
    51     return 0;
    52 }

        接下来是把 i 拆分出来后的代码!(也是我一开始的思路)。可以理解为把 i 划分成几个区间 设 i 最高位可以到 10 的 n 次方, 那么可以把 i 划分成 0 - 10的n次方-1,10的n次方-1到2*10的n次方-1。以此类推直到小于 i 的最高位上的数字。 对 i 的最高位 * 10 的 n 次方 到 i , 进行特殊处理。

     1 #include<cstdio>
     2 #include<iostream>
     3 #define rep(i,j,k) for(int i = j; i <= k; i++)
     4 #define down(i,j,k) for(int i = j; i >= k; i--)
     5 using namespace std;
     6 int f[11][10] = {0}, fabs[12] = {0};
     7 
     8 int abs(int x,int y)
     9 {
    10     if( x > y ) return x - y; else return y - x;
    11 }
    12 
    13 void init()
    14 {
    15     fabs[1] = 1;
    16     rep(i,2,10){
    17         fabs[i] = fabs[i-1] * 10;
    18     }
    19     rep(i,0,9) f[1][i] = 1;
    20     rep(i,2,10){
    21         rep(j,0,9){
    22             rep(k,0,9){
    23                 if( abs(j,k) >= 2 ){
    24                     f[i][j] += f[i-1][k];
    25                 }
    26             }
    27         }
    28     }
    29 }
    30 
    31 int work(int now)
    32 {
    33     if( !now ) return 0;
    34     int tot = 10, ans = 0;
    35     while( fabs[tot] > now ) tot--;
    36     int cur = now / fabs[tot];
    37     rep(i,1,cur-1)  ans += f[tot][i];
    38     down(i,tot-1,1){
    39             rep(j,1,9) ans += f[i][j];
    40     }
    41     now %= fabs[tot];
    42     int pre = cur;
    43     down(i,tot-1,1){
    44         cur = now / fabs[i];
    45         if( i == 1 ) cur++;
    46         for(int j = 0; j <= 9 && j < cur; j++){
    47             if( abs(pre,j) >= 2 ) ans += f[i][j];
    48         }
    49         pre = now / fabs[i];
    50         now %= fabs[i];
    51     }
    52     return ans;
    53 }
    54 
    55 int main()
    56 {
    57     init(); int n, m;
    58     scanf("%d %d", &n, &m);
    59     cout<<work(m)-work(n-1)<<endl;
    60     return 0;
    61 }
    62     

    都不难,加油!多想,勇于尝试。

    1026: [SCOI2009]windy数

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 4518  Solved: 2020
    [Submit][Status][Discuss]

    Description

    windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,在A和B之间,包括A和B,总共有多少个windy数?

    Input

    包含两个整数,A B。

    Output

    一个整数。

    Sample Input

    【输入样例一】
    1 10
    【输入样例二】
    25 50

    Sample Output

    【输出样例一】
    9
    【输出样例二】
    20

    HINT

    【数据规模和约定】

    100%的数据,满足 1 <= A <= B <= 2000000000 。

    Source

    人一我十,人十我万!追逐青春的梦想,怀着自信的心,永不放弃!仿佛已看到希望,尽管还在远方
  • 相关阅读:
    texturePacker黄色文件夹和蓝色文件夹
    自定义相机下使用clippingNode注意事项
    cocos2dx 3.3多相机下_transformUpdated bug
    一定不要在头文件中using namespace XXX
    cocos2dx 3.3将坐标由父空间转化到局部空间
    cocos2dx 3.3 getParentToNodeTransform bug
    cocos2dx 3.x designResolutionSize须主动设置
    mysql操作查询结果case when then用法举例
    java List.subList方法中的超级大陷阱
    Linux下修改Mysql的用户(root)的密码
  • 原文地址:https://www.cnblogs.com/83131yyl/p/5074076.html
Copyright © 2011-2022 走看看