HNOI2002 公交车路线
题目背景
在长沙城新建的环城公路上一共有8个公交站,分别为A、B、C、D、E、F、G、H。公共汽车只能够在相邻的两个公交站之间运行,因此你从某一个公交站到另外一个公交站往往要换几次车,例如从公交站A到公交站D,你就至少需要换3次车。
Tiger的方向感极其糟糕,我们知道从公交站A到公交E只需要换4次车就可以到达,可是tiger却总共换了n次车,注意tiger一旦到达公交站E,他不会愚蠢到再去换车。现在希望你计算一下tiger有多少种可能的乘车方案。
题目描述
无
输入格式
输入文件由bus.in读入,输入文件当中仅有一个正整数n(4<=n<=10000000),表示tiger从公交车站A到公交车站E共换了n次车。
输出格式
输出到文件bus.out。输出文件仅有一个正整数,由于方案数很大,请输出方案数除以 1000后的余数。
输入输出样例
输入 #1
6
输出 #1
8
说明/提示
8条路线分别是:
(A→B→C→D→C→D→E),(A→B→C→B→C→D→E),
(A→B→A→B→C→D→E),(A→H→A→B→C→D→E),
(A→H→G→F→G→F→E),(A→H→G→H→G→F→E),
(A→H→A→H→G→F→E),(A→B→A→H→G→F→E)。
思路:这题有点偏结论吧。。。其实是个经典的传球问题,用邻接矩阵进行建图。
此外建图的注意事项,从D到E与从F到E只建单向边,因为题面说了,只要一到E就下车,不存在到了E还返回D或F的情况。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long ll; 7 const ll mod = 1000; 8 ll n; 9 struct matrix{ 10 int col, row; 11 ll ma[9][9]; 12 }G; 13 matrix mult(matrix A, matrix B) 14 { 15 matrix C; 16 C.col = B.col , C.row = A.row; 17 memset(C.ma, 0, sizeof C.ma); 18 for(int i = 1; i <= A.row; i ++) 19 for(int j = 1; j <= B.col; j ++) 20 for(int k = 1; k <= A.col; k ++) 21 { 22 C.ma[i][j] += A.ma[i][k] * B.ma[k][j]; 23 C.ma[i][j] %= mod; 24 } 25 return C; 26 } 27 matrix mksm(matrix A, ll y) 28 { 29 matrix ret; 30 ret.col = A.col, ret.row = A.row; 31 memset(ret.ma, 0, sizeof ret.ma); 32 for(int i = 1; i <= A.col; i ++) ret.ma[i][i] = 1; 33 matrix base = A; 34 while(y) 35 { 36 if(y & 1) ret = mult(ret, base); 37 base = mult(base, base); 38 y >>= 1; 39 } 40 return ret; 41 } 42 int main() 43 { 44 scanf("%lld", &n); 45 memset(G.ma, 0, sizeof G.ma); 46 G.col = 8, G.row = 8; 47 for(int i = 1; i <= 7; i ++) 48 { 49 G.ma[i][i + 1] = 1; 50 G.ma[i + 1][i] = 1; 51 } 52 G.ma[1][8] = 1, G.ma[8][1] = 1; 53 G.ma[5][4] = 0, G.ma[5][6] = 0; 54 matrix F = mksm(G, n); 55 printf("%lld\n", F.ma[1][5]); 56 return 0; 57 }