zoukankan      html  css  js  c++  java
  • BZOJ1026: [SCOI2009]windy数

    1026: [SCOI2009]windy数

    Time Limit: 1 Sec Memory Limit: 162 MB
    Submit: 9240 Solved: 4213
    [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

    题解

    不难想思路。
    真TMD难写啊。
    具体看代码。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <cmath>
    inline long long max(long long a, long long b){return a > b ? a : b;}
    inline long long min(long long a, long long b){return a < b ? a : b;}
    inline long long abs(long long x){return x < 0 ? -x : x;}
    inline void swap(long long &x, long long &y){long long tmp = x;x = y;y = tmp;}
    inline void read(long long &x)
    {
        x = 0;char ch = getchar(), c = ch;
        while(ch < '0' || ch > '9') c = ch, ch = getchar();
        while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
        if(c == '-') x = -x;
    }
    const long long INF = 0x3f3f3f3f;
    long long dp[110][10], num[110];
    //dp[i][j]:<= i位数,最高位为j 
    
    //计算1...x - 1的windy数个数 
    long long solve(long long x)
    {
    	if(x == 0) return 1;
    	long long M = 0, tmp = x;
    	while(tmp) 
    	{
    		num[++ M] = tmp % 10;
    		tmp /= 10;
    	}
    	long long pre = num[M], re = 0;
    	for(int i = 1;i < num[M];++ i)
    		re += dp[M][i];
    	for(int i = 1;i < M;++ i)
    		for(int j = 1;j <= 9;++ j)
    			re += dp[i][j];			
    	for(long long i = M - 1;i >= 1;-- i)
    	{
    		for(long long j = 0;j < num[i];++ j)
    			if(abs(num[i + 1] - j) >= 2)
    				re += dp[i][j];
    		if(abs(num[i + 1] - num[i]) < 2) break;
    	}
    	return re;
    } 
    
    int main()
    {
    	for(long long i = 0;i <= 9;++ i) dp[1][i] = 1;
    	for(long long i = 2;i <= 11; ++ i)
    		for(long long j = 0;j <= 9;++ j)
    			for(long long k = 0;k <= 9;++ k)
    				if(abs(j - k) >= 2)
    					dp[i][j] += dp[i - 1][k];
    	long long a,b;
    	read(a), read(b);
    	if(a > b) swap(a, b);
    	printf("%lld
    ", solve(b + 1) - solve(a)); 
        return 0;
    }
    
  • 相关阅读:
    SpringMVC常用注解
    在Java 中,如何跳出当前的多重嵌套循环?
    当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
    查看远程库信息(git remote的用法)
    webpack和gulp的比较
    git pull 和git fetch的区别
    什么是性能优化?
    第一阶段的任务及燃尽图(第五天)
    第一阶段的任务及燃尽图(第二天)
    第一阶段的任务及燃尽图(第一天)
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8531095.html
Copyright © 2011-2022 走看看