• uva 10712


    题目链接:uva 10712 - Count the Numbers


    题目大意:给出n,a。b。问说在a到b之间有多少个n。


    解题思路:数位dp。dp[i][j][x][y]表示第i位为j的时候。x是否前面是相等的。y是否已经出现过n。对于n=0的情况要特殊处理前导0,写的很乱。搓死。


    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    typedef long long ll;
    const int N = 20;
    const int M = 1005;
    
    ll A, B, n, a[N], dp[N][M][2][2];
    
    void del (ll u, ll* p) {
    	ll& c = p[0];
    	c = 0;
    
    	while (u) {
    		p[++c] = u % 10;
    		u /= 10;
    	}
    
    	if (c == 0)
    		p[++c] = 0;
    
    	for (int i = 1; i <= c / 2; i++)
    		swap(p[i], p[c-i+1]);
    }
    
    ll cat (ll u) {
    
    	if (u == 0)
    		return 1;
    
    	int s = 0;
    	ll f[N][N][2];
    	memset(f, 0, sizeof(f));
    
    	for (int i = 1; i <= a[0]; i++) {
    		
    		for (int j = 0; j < 10; j++) {
    			for (int k = 0; k < 10; k++) {
    				f[i][j][1] += f[i-1][k][1];
    				if (j)
    					f[i][j][0] += f[i-1][k][0];
    				else
    					f[i][j][1] += f[i-1][k][0];
    			}
    		}
    
    		if (a[i] == 0)
    			s = 1;
    		else if (i > 1)
    			f[i][0][1]++;
    
    		for (int j = 1; j < a[i]; j++)
    			f[i][j][s]++;
    		if (i > 1) {
    			for (int j = 1; j < 10; j++)
    				f[i][j][0]++;
    		}
    	}
    
    	ll ans = 0;
    	if (s)
    		ans++;
    
    	for (int i = 0; i < 10; i++)
    		ans += f[a[0]][i][1];
    	return ans + 1;
    }
    
    ll solve (ll u) {
    	if (u < n)
    		return 0;
    
    	del(u, a);
    
    	if (n == 0)
    		return cat(u);
    
    	memset(dp, 0, sizeof(dp));
    
    	dp[0][0][1][0] = 1;
    
    	ll v = n, tmp = 1;
    
    	if (v) {
    		while (v) {
    			v /= 10;
    			tmp *= 10;
    		}
    	} else {
    		tmp = 10;
    	}
    	ll mod = tmp / 10;
    
    	for (int i = 1; i <= a[0]; i++) {
    
    		for (int j = 0; j < tmp; j++) {
    
    			for (int k = 0; k < 10; k++) {
    				int x = (j % mod) * 10 + k;
    
    				if (x == n) {
    					dp[i][x][0][1] += (dp[i-1][j][0][0] + dp[i-1][j][0][1]);
    					if (k < a[i])
    						dp[i][x][0][1] += (dp[i-1][j][1][0] + dp[i-1][j][1][1]);
    					else if (k == a[i])
    						dp[i][x][1][1] += (dp[i-1][j][1][0] + dp[i-1][j][1][1]);
    				} else {
    					dp[i][x][0][0] += dp[i-1][j][0][0];
    					dp[i][x][0][1] += dp[i-1][j][0][1];
    
    					if (k < a[i]) {
    						dp[i][x][0][0] += dp[i-1][j][1][0];
    						dp[i][x][0][1] += dp[i-1][j][1][1];
    					} else if (k == a[i]) {
    						dp[i][x][1][0] += dp[i-1][j][1][0];
    						dp[i][x][1][1] += dp[i-1][j][1][1];
    					}
    				}
    			}
    		}
    	}
    
    	int c = a[0];
    	ll ans = 0;
    	for (int i = 0; i < tmp; i++)
    		ans += (dp[c][i][0][1] + dp[c][i][1][1]);
    	return ans;
    }
    
    int main () {
    	while (scanf("%lld%lld%lld", &A, &B, &n) == 3) {
    		if (A == -1 || B == -1 || n == -1)
    			break;
    		printf("%lld
    ", solve(B) - solve(A-1));
    	}
    	return 0;
    }
    


  • 相关阅读:
    SVN 客户端的使用
    day36_Spring学习笔记_04_SVN
    VisualSVN Server 的使用图解(windows版本)
    day68_淘淘商城项目_01_电商介绍 + 互联网术语 + SOA + 分布式 + 集群介绍 + 环境配置 + 框架搭建_匠心笔记
    VisualSVN Server 的安装(windows版本)
    【代码规范神器】阿里巴巴Java开发规约IDE插件使用教程(P3C)
    学了这四招,你在Linux上观看Netflix视频不发愁
    如何在Fedora或CentOS上使用Samba共享
    Fedora 23如何安装LAMP服务器
    HTTP/HTTPS自动加密上网方案
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/8919121.html
Copyright © 2020-2023  润新知