26850: 收集數碼晶體 有40%錯誤

http://arena.acmclub.com/problem.php?id=26850php

數碼世界的國王Shoutmon想要在n個小島上舉辦一個遊戲,來讓數碼寶貝們好好玩耍。背景是這樣的:在這n個小島之間事先安放了一些單向通道,每一個通道鏈接兩個不一樣的小島,且只能按一個給定的方向經過。數碼寶貝每次由通道到達一個小島時都會令體內增長一個「數碼晶體」。ios

Shoutmon制定了一項規則,即數碼寶貝們能夠從某個小島出發,到達一個目的小島,若是到達目的小島後體內的「數碼晶體」數量剛好爲L,那麼此時能夠在小島上的兌獎處領取獎品(領完獎品後自動退出遊戲)。注意,到達目的小島後若是「數碼晶體」數量不足,那麼仍然能夠離開小島,直到某次回到目的小島時「數碼晶體」的數量剛好爲L。每一個小島(包括起始小島和目的小島)與每條通道都不限制到達和經過次數。初始狀態下體內的「數碼晶體」數量爲0。app

爲了保證活動正常進行,Shoutmon想要知道,有多少條路徑能夠從起始小島S到達目的小島T並領獎(可能有屢次查詢)。測試

 

輸入

每一個輸入文件中一組數據。spa

第一行三個整數n、m、L(2<=n<=30,0<=m<=n*(n-1),1<=L<=100),分別表明小島個數、單向通道條數、剛好須要的「數碼晶體」數。code

接下來m行,每行兩個整數u和v,表明從小島u到小島v有一條單向通道(假設小島編號爲從0到n-1)。數據保證u不等於v,且相同的有序對(u,v)最多出現一次。blog

而後一個正整數k(k<=n*n),表示查詢次數。遊戲

接着k行,每行兩個整數S和T,表示須要查詢有多少條路徑能夠從起始小島S到達目的小島T並領獎。string

 

輸出

輸出k行,每行一個整數,對應查詢的結果,即從起始小島到達目的小島並領獎的路徑條數。因爲路徑條數可能不少,所以將結果模上1000000007。it

 

樣例輸入

3 4 4 0 1 0 2 1 2 2 0 3 1 1 0 2 2 0

樣例輸出

0 2 1

提示

// hahaha.cpp : 定義控制檯應用程序的入口點。
//

#include <stdafx.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <string>
#include <cstdio>
#include <set>
#include <algorithm>
#include <string.h>

using namespace std;
const int maxn=31;
int n,m,limit;
long long hahaha[maxn][maxn][100]={0};
bool haha[maxn][maxn][100]={false};

set<int> G[maxn];
long long query(int a,int b,int li)
    {
    if(haha[a][b][li]==true)
        {
        return hahaha[a][b][li];
        }
    long long tmp=0;
    set<int>::iterator it=G[a].find(b);
    if(it!=G[a].end()&&li==1)return 1;
    if(li==0&&a!=b)return 0;
    if(li<0)return 0;
    for(set<int>::iterator it=G[a].begin();it!=G[a].end();it++)
        {
            
            hahaha[*it][b][li-1]=(query(*it,b,li-1)+1000000007)%1000000007;
            haha[*it][b][li-1]=true;
            tmp=(tmp+hahaha[*it][b][li-1])%1000000007;
        }
    return tmp;
    }

int main()
{
scanf("%d %d %d",&n,&m,&limit);
for(int i=0;i<m;i++)
    {
    int a,b;
    scanf("%d %d",&a,&b);
    G[a].insert(b);
    }
int k;
scanf("%d",&k);
for(int i=0;i<k;i++)
    {
    int a,b;
    scanf("%d %d",&a,&b);
    long long count=query(a,b,limit);
    long long jieguo=count%1000000007;
    printf("%lld\n",jieguo);
    }
     
    
    return 0;
}
測試文件:/4.out   結果:答案錯誤
	=======緣由======
	當參考答案輸出:
	280157144
	-------時---------
	你的程序輸出:
	0
	=================
測試文件:/0.out   結果:答案正確
測試文件:/2.out   結果:答案正確
測試文件:/3.out   結果:答案正確
測試文件:/1.out   結果:答案錯誤
	=======緣由======
	當參考答案輸出:
	505425294
	-------時---------
	你的程序輸出:
	0
	=================

   正解

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 60;
const long long MOD = 1000000007;
long long G[maxn][maxn], ans[maxn][maxn], temp[maxn][maxn];

void MatrixPow(int n, int L) {
    for(int times = 0; times < L; times++) {
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                temp[i][j] = 0;
                for(int k = 0; k < n; k++) {
                    temp[i][j] = (temp[i][j] + (ans[i][k] * G[k][j] % MOD + MOD)) % MOD;
                }
            }
        }
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                ans[i][j] = temp[i][j];
            }
        }
    }
}

void init() {
    memset(G, 0, sizeof(G));
    memset(ans, 0, sizeof(ans));
    for(int i = 0; i < maxn; i++) {
        ans[i][i] = 1;
    }
}

int main() {
        init();
        int n, m, L, u, v;
        scanf("%d%d%d", &n, &m, &L);
        for(int i = 0; i < m; i++) {
            scanf("%d%d", &u, &v);
            G[u][v] = 1;
        }
        MatrixPow(n, L);
        int k;
        scanf("%d", &k);
        for(int i = 0; i < k; i++) {
            scanf("%d%d", &u, &v);
            printf("%lld\n", (ans[u][v] % MOD + MOD) % MOD);
        }
    return 0;
}
相關文章
相關標籤/搜索