UVa 12796 - Teletransport

contents

  1. 1. Problem
  2. 2. Sample Input
  3. 3. Sample Output
  4. 4. Solution

Problem

目標從太空船 S 到太空船 T,每一個太空船上有 N 個按鈕,每一種按鈕可以傳送到指定的太空船上,請問 L 步從 S 到 T 的按法有幾種。

Sample Input

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2 20
1 1
2 2 2 2
1 1 1 1
2 29
1 1
2 2 2 2
1 1 1 1
2 0
1 1
2 2 2 2
1 1 1 1
2 0
1 2
2 2 2 2
1 1 1 1
3 2
3 1
1 2 2 2
2 1 3 2
2 2 3 1

Sample Output

1
2
3
4
5
7776
0
1
0
4

Solution

既然按鈕都不同,那就可以轉換成一般的 Graph,然後轉化成 K 步內抵達的方法數。

直接利用矩陣相乘計算方法數!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <stdio.h>
#include <string.h>
const int mod = 10000;
struct Matrix {
int v[100][100];
int row, col; // row x col
Matrix(int n, int m, int a = 0) {
memset(v, 0, sizeof(v));
row = n, col = m;
for(int i = 0; i < row && i < col; i++)
v[i][i] = a;
}
Matrix operator*(const Matrix& x) const {
Matrix ret(row, x.col);
for(int i = 0; i < row; i++) {
for(int k = 0; k < col; k++) {
if (v[i][k])
for(int j = 0; j < x.col; j++) {
ret.v[i][j] += v[i][k] * x.v[k][j],
ret.v[i][j] %= mod;
}
}
}
return ret;
}
Matrix operator^(const int& n) const {
Matrix ret(row, col, 1), x = *this;
int y = n;
while(y) {
if(y&1) ret = ret * x;
y = y>>1, x = x * x;
}
return ret;
}
};
int main() {
int N, L, S, T;
int x, y;
while (scanf("%d %d", &N, &L) == 2) {
scanf("%d %d", &S, &T);
Matrix m(N, N);
for (int i = 0; i < N; i++) {
for (int j = 0; j < 4; j++) {
scanf("%d", &x), x--;
m.v[i][x]++;
}
}
Matrix ret = m ^ L;
S--, T--;
printf("%d\n", ret.v[S][T]);
}
return 0;
}
/*
2 20
1 1
2 2 2 2
1 1 1 1
2 29
1 1
2 2 2 2
1 1 1 1
2 0
1 1
2 2 2 2
1 1 1 1
2 0
1 2
2 2 2 2
1 1 1 1
3 2
3 1
1 2 2 2
2 1 3 2
2 2 3 1
*/