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

Posted 蒟蒻zht的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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", c);
    return c;
}

struct Big_int
{
    int s[MAXN], idx;
    Big_int()
    {
        idx = 0;
        memset(s, 0, sizeof(s));
    }
    inline void operator = (char *c)
    {
        idx = strlen(c);
        for(int i = 0; i < idx; i++) s[i] = c[idx - i - 1] - ‘0‘;
    }
    inline void operator = (int x)
    {
    	idx = 0;
    	if(!x) idx++, s[0] = 0;
        while(x)
        {
            s[idx] = x % 10;
            x /= 10;
            idx++;    
        }
    }
    inline void print()
    {
        if(!idx) printf("0");
        else for(int i = idx - 1; i >= 0; i--) printf("%d", s[i]);
        puts("");
    }
};

inline Big_int operator + (const Big_int x, const Big_int y)
{
    Big_int ret;
    ret.idx = max(x.idx, y.idx) + 1;
    for(int i = 0; i < ret.idx; i++)
    {
        ret.s[i] += x.s[i] + y.s[i];
        if(ret.s[i] >= 10)
            ret.s[i + 1] += 1, ret.s[i] -= 10;
    }
    while(!ret.s[ret.idx - 1] && ret.idx > 1) ret.idx--;
    return ret;
}

inline bool operator < (const Big_int x, const Big_int y)
{
    if(x.idx < y.idx) return 1;
    if(x.idx > y.idx) return 0;
    for(int i = x.idx - 1; i >= 0; i--)
        if(x.s[i] ^ y.s[i])
            return x.s[i] < y.s[i];
    return 0;
}

inline Big_int operator - (Big_int x, Big_int y)
{
    Big_int ret;
    if(x < y) swap(x, y);
    ret.idx = x.idx;
    for(int i = 0; i < ret.idx; i++)
    {
        if(x.s[i] < y.s[i])
        {
            x.s[i] += 10;
            x.s[i + 1]--;
        }
        ret.s[i] = x.s[i] - y.s[i];
    }
    while(!ret.s[ret.idx - 1] && ret.idx > 1) ret.idx--;
    return ret;
}

inline Big_int operator * (const Big_int x, const Big_int y)
{
    Big_int ret;
    ret.idx = x.idx + y.idx;
    for(int i = 0; i < x.idx; i++)
        for(int j = 0; j < y.idx; j++)
        {
            ret.s[i + j] += x.s[i] * y.s[j];
            ret.s[i + j + 1] += ret.s[i + j] / 10;
            ret.s[i + j] %= 10;
        }
    while(!ret.s[ret.idx - 1] && ret.idx > 1) ret.idx--;
    return ret;
}

Big_int a, ans;

int main()
{
    int i, j, k, x, y;
	scanf("%s", s);
    scanf("%d", &k);
    for(i = 1; i <= k; i++)
    {
    	scanf("%d %d", &x, &y);
    	map[x][y] = 1;
    }
    for(i = 0; i <= 9; i++) map[i][i] = 1;
    for(k = 0; k <= 9; k++)
    	for(i = 0; i <= 9; i++)
    		for(j = 0; j <= 9; j++)
    			map[i][j] = map[i][j] || (map[i][k] && map[k][j]);
	ans = 1;
    k = strlen(s);
	for(i = 0; i < k; i++)
    {
    	x = 0;
    	for(j = 0; j <= 9; j++)
    		if(map[s[i] - ‘0‘][j]) x++;
		a = x;
    	ans = ans * a;
    }
    ans.print();
    return 0;
}

  

以上是关于[luoguP1037] 产生数(floyd + 高精度)的主要内容,如果未能解决你的问题,请参考以下文章

luogu_1037 产生数

NOIP2002pj产生数[floyd 高精度]

[Luogu] 产生数

BZOJ 1037 [ZJOI2008]生日聚会Party(单调DP)

[luoguP2886] [USACO07NOV]牛继电器Cow Relays(矩阵)

bzoj 1037 [ZJOI2008]生日聚会Party dp