zoukankan      html  css  js  c++  java
  • [洛谷P3413]SAC#1

    题目大意:求$[l,r](0leqslant l<r< 10^{1001})$中存在长度至少为$2$的回文串的数字数

    题解:数位$DP$,发现如果有回文串,若长度为偶数,一定有两个相同的数字相邻;若长度为奇数,一定有两个相同的数字中间间隔一个数字。所以只需要记录前两个数字就行了。注意判断$l$是否符合条件。

    卡点:

    C++ Code:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define maxn 1010
    const long long mod = 1e9 + 7;
    
    char l[maxn], r[maxn];
    int num[maxn], tot;
    long long f[maxn][11][11][2];
    long long calc(int x, int lim, int lead, int lst_2, int lst, int had) {
    	if (!x) return had;
    	long long F = f[x][lst_2][lst][had];
    	if (!lim && lead && ~F) return F;
    	F = 0;
    	for (int i = lim ? num[x] : 9, op = 1; ~i; i--, op = 0) {
    		F += calc(x - 1, lim && op, lead || i, lst, (lead || i) ? i : 10, had || (i == lst_2) || (i == lst));
    	}
    	F %= mod;
    	if (!lim && lead) f[x][lst_2][lst][had] = F;
    	return F;
    }
    long long solve(char *x) {
    	int len = strlen(x);
    	for (int i = 0; i < len; i++) num[len - i] = x[i] & 15;
    	return calc(len, 1, 0, 10, 10, 0);
    }
    long long check(char *x) {
    	int len = strlen(x);
    	for (int i = 1; i < len; i++) if (x[i] == x[i - 1]) return 1;
    	for (int i = 2; i < len; i++) if (x[i] == x[i - 2]) return 1;
    	return 0;
    }
    
    int main() {
    	scanf("%s%s", l, r);
    	memset(f, -1, sizeof f);
    	printf("%lld
    ", (solve(r) - solve(l) + mod + check(l)) % mod);
    	return 0;
    }
    

      

  • 相关阅读:
    第一次MVC记录
    Treeview绑定以及添加多选功能
    BindingSource的使用
    WPF实现环(圆)形进度条
    WPF实现环(圆)形菜单
    WPF实现音乐字幕动画
    WPF加载高德地图
    WPF实现Android(3D)菜单翻转动画
    WPF实现头像裁剪
    WPF PointAnimationUsingKeyFrames 动画
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9835946.html
Copyright © 2011-2022 走看看