NOIP2002pj产生数[floyd 高精度]

背景

给出一个整数 n(n<10^30) 和 k 个变换规则(k<=15)。

规则:
一位数可变换成另一个一位数:
规则的右部不能为零。

例如:n=234。有规则(k=2):
2-> 5
3-> 6
上面的整数 234 经过变换后可能产生出的整数为(包括原数):
234
534
264
564
共 4 种不同的产生数

描述

给出一个整数 n 和 k 个规则。

求出:
经过任意次的变换(0次或多次),能产生出多少个不同整数。

仅要求输出个数。

格式

输入格式

n k
x1 y1
x2 y2
... ...
xn yn

输出格式

一个整数(满足条件的个数):

样例1

样例输入1[复制]

234 2
2 5
3 6

样例输出1[复制]

4

限制

每个测试点1s

来源

noip2002普及组第三题

----------------

一个数可以变换多次,floyd求传递闭包(初始化d[i][i]=1),乘法原理更新答案

要用高精度,注意输出

//
//  main.cpp
//  noip2002产生数
//
//  Created by Candy on 9/10/16.
//  Copyright © 2016 Candy. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef unsigned long long ll;
const int N=55,B=1e4;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}

int k,x,y,d[N][N],f[N];
char s[N];
void floyd(){
    for(int i=0;i<=9;i++) d[i][i]=1;
    for(int k=0;k<=9;k++)
        for(int i=0;i<=9;i++)
            for(int j=0;j<=9;j++)
                d[i][j]=d[i][j]||(d[i][k]&&d[k][j]);
    for(int i=0;i<=9;i++)
        for(int j=0;j<=9;j++) if(d[i][j]) f[i]++;
}
struct big{
    int d[100],size;
    big(){size=1;}
} ans;
void chengInt(big &a,int k){
    int g=0,i;
    for(i=1;i<=a.size;i++){
        int tmp=a.d[i]*k;
        a.d[i]=(tmp+g)%B;
        g=(tmp+g)/B;
    }
    while(g){
        a.d[i++]=g%B; a.size++;
        g/=B;
    }
}
int main(int argc, const char * argv[]) {
    scanf("%s%d",s,&k);
    for(int i=1;i<=k;i++) scanf("%d%d",&x,&y),d[x][y]=1;
    floyd();
    ans.d[1]=1;
    int len=strlen(s);
    for(int i=0;i<len;i++){
        int a=s[i]-‘0‘;
        chengInt(ans,f[a]);
        //printf("f %d %d\n",a,f[a]);
    }
    for(int i=ans.size;i>=1;i--){
        if(i!=ans.size){
            if(ans.d[i]<10) cout<<"000";
            else if(ans.d[i]<100) cout<<"00";
            else if(ans.d[i]<1000) cout<<"0";
        }
        cout<<ans.d[i];
    }
    return 0;
}
时间: 2024-08-07 14:40:24

NOIP2002pj产生数[floyd 高精度]的相关文章

卡特兰数,高精度卡特兰数

简介:卡特兰数是组合数学中经常出现的一个数列. 个人觉得无论是递推公式还是代表的含义都比斐波那契数列难理解一些. 递推公式: 应用: 1.Cn表示长度2n的dyck word的个数.Dyck word是一个有n个X和n个Y组成的字串,且所有的前缀字串皆满足X的个数大于等于Y的个数.以下为长度为6的dyck words XXXYYY XYXXYY XYXYXY XXYYXY XXYXYY 分析:对于n个X,n个Y的排列来说一共有C(n,2n)种,还要排除其中不符合要求的排列.不符合条件的排列对于某

[luoguP1037] 产生数(floyd + 高精度)

传送门 先用 floyd 求出每一个数可以变成那些数. 然后利用乘法原理求解,需要高精度. 代码 #include <cstdio> #include <cstring> #include <iostream> using namespace std; const int MAXN = 101; char s[MAXN]; char c[MAXN]; int map[10][10]; inline char *read() { scanf("%s",

TYVJ 矩阵取数 Label:高精度+dp

题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2.每次取走的各个元素只能是该元素所在行的行首或行尾: 3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值*2^i,其中i表示第i次取数(从1开始编号): 4.游戏结束总得分为m次取数得分之和. 帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分. 输入输

BZOJ 2822 AHOI 2012 树屋阶梯 卡特兰数+高精度

题目大意:高精度卡特兰数. 思路:上维基上看看,有一个模型和这个题一模一样,然后就剩下水水的高精度了. (谁来教教我java... CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define BASE 10000 #define MAX 100010 using namespace std; struct BigInt{ int num

洛谷 P1255 数楼梯 高精度加法

P1255 数楼梯 时空限制1s / 128MB 题目描述 楼梯有N阶,上楼可以一步上一阶,也可以一步上二阶. 编一个程序,计算共有多少种不同的走法. 输入输出格式 输入格式: 一个数字,楼梯数. 输出格式: 走的方式几种. 输入输出样例 输入样例#1: 4 输出样例#1: 5 说明 用递归会太慢,需用递推 (60% N<=50 ,100% N<=5000) --------------------------------------------------------------------

【BZOJ2822】【AHOI2012】树屋阶梯 卡特兰数 python高精度

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43404565"); } 题解: 首先考虑在当前情况下多加一层,那么我们可以枚举最后一层台阶长度来得到答案. 最后得到的是卡特兰数. 代码: f=[0]*60 f[1]=1 n=int(raw_input()) for i in range(2,n+1

随手练——麦森数(高精度快速幂)

https://www.luogu.org/problemnew/show/P1045 第一步:求位数 第二步:高精度快速幂的实现 第一版: 用vector做的,中间把超过500位的去除,但是实际跑起来比较慢 #include <iostream> #include <stdio.h> #include <math.h> #include <vector> #include <algorithm> using namespace std; int

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

CIKM Competition数据挖掘竞赛夺冠算法陈运文

CIKM Competition数据挖掘竞赛夺冠算法陈运文 背景 CIKM Cup(或者称为CIKM Competition)是ACM CIKM举办的国际数据挖掘竞赛的名称.CIKM全称是International Conference on Information and Knowledge Management,属于信息检索和数据挖掘领域的国际著名学术会议,由ACM SIGIR分会(ACM Special Interest Group on Information Retrieval)主办.