hihocoder1560 H国的身份证号码II

题意:输入n,m问满足条件的n位数有几个条件:首位不能为0,相邻的数乘积不能超过k,每一位数不能超过k

题解:10*10的矩阵

#include <bits/stdc++.h>
#define ll long long
#define maxn 10
using namespace std;
ll mod = 1e9+7;
struct mat{
    ll m[maxn][maxn], len;
    mat(){memset(m, 0, sizeof(m));len=maxn;}
    mat friend operator*(mat a,mat b){
        mat d;
        for(ll i=0;i<a.len;i++)
            for(ll j=0;j<b.len;j++)
                for(ll k=0;k<b.len;k++)
                d.m[i][j] = (d.m[i][j]%mod+(a.m[i][k]*b.m[k][j])%mod)%mod;
        return d;
    }
};
mat f(mat x,ll num){
    mat t;
    for(ll i=0;i<t.len;i++) t.m[i][i] = 1;
    while(num){
        if(num&1) t = t*x;
        x = x*x;
        num >>= 1;
    }
    return t;
}
ll ff(ll x,ll t,ll m){
    ll ans=1;
    while(t){
        if(t&1) ans = ans*x%m;
        x = x*x%m;
        t >>= 1;
    }
    return ans;
}
int main(){
    ll n,k, ans = 0;
    cin>>n>>k;
    mat t, fi;
    for(ll i=0;i<10;i++)
        for(ll j=0;j<10;j++){
            if(i*j<=k&&i<=k&&j<=k) t.m[i][j] = 1;
            else t.m[i][j] = 0;
        }
    for(ll i=0;i<10;i++)
        if(i<=k) fi.m[0][i] = 1;
    t = fi*f(t, n-1);
    for(int i=1;i<10;i++) ans = (ans+t.m[0][i])%mod;
    cout<<ans<<endl;
    return 0;
}
时间: 2024-10-07 10:47:04

hihocoder1560 H国的身份证号码II的相关文章

#1560 : H国的身份证号码II(dp+矩阵快速幂)

#1560 : H国的身份证号码II 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 H国的身份证号码是一个N位的正整数(首位不能是0).此外,由于防伪需要,一个N位正整数是合法的身份证号码当且仅当每位数字都小于等于K,并且任意相邻两位数字的乘积也小于等于K. 例如对于K=5, 101.211.210等都是合法的号码,而106.123.421等都是非法的号码. 给定一个正整数N以及K,H国总统想知道一共有多少个合法的号码可用. 输入 两个整数N和K. 对于30%的数

H国的身份证号码(搜索)

个人心得:巧妙利用数字进行维护就好了,深搜还是有点心得的: #1558 : H国的身份证号码I 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 H国的身份证号码是一个N位的正整数(首位不能是0).此外,由于防伪需要,一个N位正整数是合法的身份证号码当且仅当每位数字都小于等于K,并且任意相邻两位数字的乘积也小于等于K. 例如对于K=5, 101.211.210等都是合法的号码,而106.123.421等都是非法的号码. 给定一个正整数N以及K,请从小到大输出所有合法的

算法提高 身份证号码升级

问题描述 从1999年10月1日开始,公民身份证号码由15位数字增至18位.(18位身份证号码简介).升级方法为: 1.把15位身份证号码中的年份由2位(7,8位)改为四位. 2.最后添加一位验证码.验证码的计算方案: 将前 17 位分别乘以对应系数 (7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2) 并相加,然后除以 11 取余数,0-10 分别对应 1 0 x 9 8 7 6 5 4 3 2. 请编写一个程序,用户输入15位身份证号码,程序生成18位身份证号码.假设所

身份证号码合法性判断

问题描述: 我国公民的身份证号码特点如下: 1.长度为18位: 2.第1-17位只能为数字: 3.第18位可以是数字或者小写英文字母x. 4.身份证号码的第7~14位表示持有人生日的年.月.日信息. 例如:511002198808080111或51100219880808011x. 请实现身份证号码合法性判断的函数.除满足以上要求外,需要对持有人生日的年.月.日信息进行校验.年份大于等于1900年,小于等于2100年.需要考虑闰年.大小月的情况.所谓闰年,能被4整除且不能被100整除或能被400

身份证号码识别

我国公民的身份证号码特点如下: 1.     长度为18位: 2.     第1-17位只能为数字: 3.     第18位可以是数字或者小写英文字母x. 4.     身份证号码的第7~14位表示持有人生日的年.月.日信息. 例如:511002198808080111或51100219880808011x. 请实现身份证号码合法性判断的函数.除满足以上要求外,需要对持有人生日的年.月.日信息进行校验.年份大于等于1900年,小于等于2100年. 需要考虑闰年.大小月的情况.所谓闰年,能被4整除

身份证号码18个数字代表的意思

一.前言介绍 中华人民共和国公民身份号码是中华人民共和国为中国大陆每个公民从出生之日起编定的唯一的.终身不变的身份代码,在中华人民共和国公民办理涉及政治.经济.社会生活等权益事务方面广泛使用.中华人民共和国公安部负责公民身份号码的编制和组织实施工作. 1999年8月26日中华人民共和国国务院发布<国务院关于实行公民身份号码制度的决定>(国发[1999]15号),这个文件规定自1999年10月1日起在全国建立和实行公民身份号码制度. 二.数字组成方式 1.地址码(身份证号码前六位) 表示编码对象

身份证号码

function checkidcard(str) { var temp = {}; if (id_cards.checkCard(str)) { temp.msg = ""; temp.statu = true; return temp; } else { temp.msg = "身份证号格式不正确"; temp.statu = false; return temp; } } //身份证号码 var id_cards = { cities: { 11: "

身份证号码编码规则

18 位身份证号码编码规则:根据[中华人民共和国国家标准 GB 11643-1999]中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码.可以用字母表示如为 ABCDEFYYYYMMDDXXXR.其含义如下: 1. 地址码(ABCDEF):表示编码对象常住户口所在县(市.旗.区)的行政区划代码,按 GB/T2260 的规定执行. 2. 出生日期码(YYYYMMDD)

身份证号码升级

问题描述 从1999年10月1日开始,公民身份证号码由15位数字增至18位.(18位身份证号码简介).升级方法为: 1.把15位身份证号码中的年份由2位(7,8位)改为四位. 2.最后添加一位验证码.验证码的计算方案: 将前 17 位分别乘以对应系数 (7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2) 并相加,然后除以 11 取余数,0-10 分别对应 1 0 x 9 8 7 6 5 4 3 2. 请编写一个程序,用户输入15位身份证号码,程序生成18位身份证号码.假设所