CODE [VS] 1009 产生数 (用Floyd算法求解传递闭包)

题目链接:http://codevs.cn/problem/1009/

问题分析:很明显,扫描一遍字符串,遇到可以变换的数字,将这个可以变换的数字的所有可能情况的数目乘起来便是我们要的答案。现在的问题便是如何求解单个数字的所有可能情况。而这可以通过求解数字 0-9 之间的邻接矩阵的传递闭包的方法求解出来。用floyd算法即可。

ps:有人会问,floyd算法为何可以求解传递闭包?理由很简单,floyd算法可以求解出邻接矩阵中任意两个点之间的最短距离,让一个邻接矩阵跑完floyd算法之后,再扫描一遍该邻接矩阵,如果两点(i -> j )之间的距离不为正无穷,那这两个点就是可达(i -> j)。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <sstream>
#define PI acos(-1.0)
const int  inf =  (1<<30) - 10;
using namespace std;

char str[35];   //用来存放 n ,因为数字 n 比较大,所以用字符串类型储存
int f[11][11];  //存放数字 0 - 9 的邻接矩阵
int sum[11];    //存放数字可以变化的情况数,比如sum[0]就是数字 ‘0’可以变化成其他数字的数目
int m;

void init()  //初始化
{
    for(int i = 0;i < 11; ++i)
    {
        sum[i] = 0;
        for(int j = 0;j < 11; ++j)
        {
            if(i == j)
            {
                f[i][j] = 0;
            }
            else
            {
                f[i][j] = inf;
            }
        }
    }
}

void input() //输入
{
    int x, y;
    scanf("%s%d",str,&m);
    for(int i = 0;i < m; ++i)
    {
        scanf("%d%d",&x,&y);
        f[x][y] = 1;
    }
}

void floyd() //求解传递闭包
{
    for(int k = 0;k <= 9; ++k)
    {
        for(int i = 0;i <= 9; ++i)
        {
            if(f[i][k])
            for(int j = 0;j <= 9; ++j)
            {
                f[i][j] = min(f[i][j],f[i][k]+f[k][j]);
            }
        }
    }
}

void solved()
{
    for(int i = 0;i <= 9; ++i)
        for(int j = 0;j <= 9; ++j)
            if(f[i][j] < inf)
                sum[i]++;         //只要 i 与 j 之间可达(我这里的判断方法是,距离不为正无穷),sum[i] 便加一

    long long ans = 1;
    for(int i = 0; str[i] != '\0'; ++i)
    {
        ans *= sum[str[i] - '0']; //组合数学,用乘法求解所有可能出现的情况
    }
    cout<<ans<<endl;
}

int main()
{
    init();   ///初始化
    input();  ///输入数据
    floyd();  ///用Floyd算法求解传递闭包
    solved(); ///输出答案
    return 0;
}

如有BUG,欢迎指出!

时间: 2024-08-28 19:13:34

CODE [VS] 1009 产生数 (用Floyd算法求解传递闭包)的相关文章

POJ3660 传递闭包———floyd算法

POJ3660 Cow Contest 题目链接:http://poj.org/problem?id=3660 题意:农名约翰有些奶牛,约翰通过让他们决斗来决定他们的排名,约翰让这些奶牛一对一打完一定的局数之后,问有哪些奶牛的排名是可以确定的(注:a打得过b,b打得过c,则a打得c) 根据题意我们明白当一个奶牛和其他的所有奶牛都存在胜负关系的时候,他的排名就是确定的. 思路:利用floyd算法,传递闭包,算出可达矩阵.然后在每一行去查询该点和其他所有的点的联系是不是n-1. 代码: //Auth

POJ 2112 Optimal Milking 最优挤奶方案 Floyd算法+二分查找+最大流

题目链接:POJ 2112 Optimal Milking Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12446   Accepted: 4494 Case Time Limit: 1000MS Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among

[C++] 多源最短路径(带权有向图):【Floyd算法(动态规划法)】 VS nX Dijkstra算法(贪心算法)

1 Floyd算法 1.1 Code /** * 弗洛伊德(Floyd)算法: 1 解决问题: 多源最短路径问题 求每一对顶点之间的最短路径 Background: 带权有向图 2 算法思想: 动态规划(DP, Dynamic Programming) 3 时间复杂度: O(n^3) */ #include<stdio.h> #include<iostream> using namespace std; // 1 定义图模型(邻接矩阵表示法)的基本存储结构体 # define Ma

ACM: POJ 3660 Cow Contest - Floyd算法

链接 Cow Contest Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Eac

最短路径Dijkstra算法和Floyd算法整理、

转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径—Dijkstra算法和Floyd算法 Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹

最短路径—Dijkstra算法和Floyd算法

Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等.注意该算法要求图中不存在负权边. 问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径.(单源最短路径) 2.算法

hiho一下 第二十四周---最短路径&#183;二:Floyd算法

最短路径·二:Floyd算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的中午,小Hi和小Ho在吃过中饭之后,来到了一个新的鬼屋! 鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点的道路. 由于没有肚子的压迫,小Hi和小Ho决定好好的逛一逛这个鬼屋,逛着逛着,小Hi产生了这样的问题:鬼屋中任意两个地点之间的最短路径是多少呢? 提示:其实如果你开心的话,完全可以从

中间的球( floyd算法 )

中间的球 Time Limit: 1000 MS Memory Limit: 32767 K Total Submit: 97(37 users) Total Accepted: 48(35 users) Rating: Special Judge: No Description 有N个外形一样但重量不同的球,N是一个奇数,每个球被标号为1.2.....N,你的任务是 找到重量在中间的那个球, 我们可以通过一些比较得知某些球比其他的球要中或者轻,从而找 到一些不可能是重量处在中间的球,比如: 给

“Chaos”的算法之Floyd算法

倘若我们要在计算机上建立一个交通咨询系统则可以采用图的结构来表示实际的交通网络.其实现最基本的功能,求出任意两点间的最短路径, 求最短路径的经典方法有很多种,最常用的便是迪杰斯特拉算法和佛洛依德(Floyd)算法,这篇文章就着重介绍Floyd算法. 求两点之间的最短路径无外乎有两种情况,一种就是从一点直接到另一点,另一种就是从一点经过n个节点后再到另一个节点,比如说要从A到B,则有两种情况就是A直接到B,或者是从A经过N个节点后再到B,所以,我们假设Dis(AB)为节点A到节点B的最短路径的距离