hdoj 2254 奥运 【矩阵快速幂 + STLmap】 【离散数学的应用】



奥运

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2585    Accepted Submission(s): 650


Problem Description
北京迎来了第一个奥运会,我们的欢呼声响彻中国大地,所以今年的奥运金牌 day day up!
比尔盖兹坐上鸟巢里,手里摇着小纸扇,看的不亦乐乎,被俺们健儿的顽强拼搏的精神深深的感动了。反正我的钱也多的没地方放了,他对自己说,我自己也来举办一个奥运会,看谁的更火。不过他的奥运会很特别:
1 参加人员必须是中国人;
2 至少会加法运算(因为要计算本人获得的金牌数)
他知道中国有很多的名胜古迹,他知道自己在t1 到 t2天内不可能把所有的地方都玩遍,所以他决定指定两个地方v1,v2,如果参赛员能计算出在t1到t2天(包括t1,t2)内从v1到v2共有多少种走法(每条道路走需要花一天的时间,且不能在某个城市停留,且t1=0时的走法数为0),那么他就会获得相应数量的金牌,城市的总数<=30,两个城市间可以有多条道路
,每条都视为是不同的。
 

Input
本题多个case,每个case:
输入一个数字n表示有n条道路 0<n<10000
接下来n行每行读入两个数字 p1,p2 表示城市p1到p2有道路,并不表示p2到p1有道路 (0<=p1,p2<2^32)
输入一个数字k表示有k个参赛人员 
接下来k行,每行读入四个数据v1,v2,t1,t2 (0<=t1,t2<10000)
 

Output
对于每组数据中的每个参赛人员输出一个整数表示他获得的金牌数(mod 2008)
 

Sample Input
       
       
       
       
6 1 2 1 3 2 3 3 2 3 1 2 1 3 1 2 0 0 1 2 1 100 4 8 3 50
 

Sample Output
       
       
       
       
0 1506 0
 



做这道题前建议先做  点我。搞懂之后,这道题就很简单了。貌似题目数据很弱。。。


不用STL,离散化也可以写吧,偷懒用了STL。

AC代码:


#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
#define MAXN 10000+1
#define MOD 2008
#define LL long long
using namespace std;
struct Matrix
{
    int a[31][31];
};
Matrix day[MAXN];
int city;//城市数 也是矩阵的行数或列数
Matrix muitl(Matrix x, Matrix y)
{
    Matrix z;
    memset(z.a, 0, sizeof(z.a));
    for(int i = 1; i <= city; i++)
    {
        for(int k = 1; k <= city; k++)
        {
            if(x.a[i][k] == 0) continue;
            for(int j = 1; j <= city; j++)
                z.a[i][j] = (z.a[i][j] + (x.a[i][k] * y.a[k][j])%MOD) % MOD;
        }
    }
    return z;
}
map<int, int> fp;
int main()
{
    int m;
    while(scanf("%d", &m) != EOF)
    {
        int s, e;
        city = 0;
        memset(day[1].a, 0, sizeof(day[1].a));
        fp.clear();
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d", &s, &e);
            if(!fp[s])
                fp[s] = ++city;
            if(!fp[e])
                fp[e] = ++city;
            day[1].a[fp[s]][fp[e]]++;//一天可以走的方案
        }
        for(int i = 2; i < MAXN; i++)//求解 第i天的方案数
            day[i] = muitl(day[i-1], day[1]);
        int q, v1, v2, t1, t2;
        scanf("%d", &q);
        while(q--)
        {
            scanf("%d%d%d%d", &v1, &v2, &t1, &t2);
            if(!fp[v1] || !fp[v2])//不存在方案
                printf("0\n");
            else
            {
                LL ans = 0;
                int temp;
                if(t1 > t2)//因为题目没有说明t1 <= t2 就加了个判断
                {
                    temp = t1;
                    t1 = t2;
                    t2 = temp;
                }
                for(int i = t1; i <= t2; i++)
                    ans += day[i].a[fp[v1]][fp[v2]], ans %= MOD;
                printf("%lld\n", ans);
            }
        }
    }
    return 0;
}


你可能感兴趣的:(hdoj 2254 奥运 【矩阵快速幂 + STLmap】 【离散数学的应用】)