MZ test17# NOIP模拟题 # T4 第4题 路线统计(route.cpp/pas)[key:矩阵]

来源:互联网 发布:农村淘宝和快递公司 编辑:程序博客网 时间:2024/06/05 15:08

第4题 路线统计(route.cpp/pas)

 

【问题描述】

给出一个n个点有向图,求从s点到f点恰好经过时间t的路径总数。不能在某个点停留,可以重复的走各点。

 

【输入数据】

第一行包含一个整数n, 所有点是从0到n-1编号.

接下来n行,每行包含n个字符. 第i行第j个字符表示i到j需要的时间,字符只可能是’1’到’5’, 或者是’.’表示i不能到达j, 保证主对角线都是’.’。

接下来一行3个整数s, f, t。

 

【输出数据】

输出总方案数mod 502630的值。

 

【样例输入】route.in

3

.12

2.1

12.

0 2 5

 

【样例输出】route.out

8

 

【数据范围及提示】

对于20%的数据, 输入的字符不是’1’就是’.’;

对于100%的数据, 1 <= n <= 10; 1 <= s,f <= n; 1 <= t <= 10^9

 

#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int MOD=502630;struct matrix{  int f[55][55];    void clear()  {  memset(f,0,sizeof(f));  }  }st,ans,E;int n;char s[15];void readdata(){  st.clear();  scanf("%d",&n);    for(int i=1;i<=n;i++)  {  scanf("%s",s);  for(int j=1;j<=n;j++)  {    if(s[j-1]!='.')    {    int ret=s[j-1]-'0';    for(int k=1;k<ret;k++)    {    st.f[(k-1)*n+i][k*n+i]=1;    }    st.f[(ret-1)*n+i][j]=1;    }  }  }    n*=5;    E.clear();    for(int i=1;i<=n;i++)E.f[i][i]=1;  }matrix o_o(matrix a,matrix b){   matrix c;  c.clear();  for(int i=1;i<=n;i++)  for(int j=1;j<=n;j++)  for(int k=1;k<=n;k++)  {  c.f[i][j]=(c.f[i][j]+((long long)a.f[i][k]*b.f[k][j])%MOD)%MOD;  }  return c;}matrix mult(matrix a,int t){  matrix c=E;  while(t)  {  if(t%2)c=o_o(c,a);    t>>=1;    a=o_o(a,a);  }  return c;}void work(){  int start,finish,t;  scanf("%d%d%d",&start,&finish,&t);  start++;finish++;    matrix ans=mult(st,t);    printf("%d\n",ans.f[start][finish]);  }int main(){freopen("route.in","r",stdin);freopen("route.out","w",stdout);readdata();work();return 0;}

附glk's code.

#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int mod = 502630;#define LL long longstruct Mat{int A[300][300];int h,l;Mat() {memset(A,0,sizeof(A));h = l = 0;}Mat operator * (const Mat& B)const{Mat C;C.h = h;C.l = B.l;for(int i = 1;i <= h;++i)for(int j = 1;j <= B.l;++j){int tmp = 0;for(int k = 1;k <= l;++k)tmp = (tmp + ((LL)A[i][k] * B.A[k][j])%mod)%mod;C.A[i][j] = tmp;}return C;}};char Can[15][15];Mat Pow(Mat B,int n){Mat ans = B;for(int i = 1;i <= B.h;++i)for(int j = 1;j <= B.l;++j)ans.A[i][j] = (i==j);while(n){if(n&1) ans = ans * B;B = B * B;n>>=1;}return ans;}int main(){freopen("route.in","r",stdin);freopen("route.out","w",stdout);//A*A为t=2,A^k means  t = k + 1//ans = A^(t-1)[s,f]int n,tot,s,f,t;scanf("%d",&n);for(int i = 1;i <= n;++i)scanf("%s",Can[i]+1);tot = n;scanf("%d%d%d",&s,&f,&t);++s,++f;Mat B;#define CC B.Afor(int i = 1;i <= n;++i){for(int j = 1;j <= n;++j){if(Can[i][j]=='.') continue;int tmp = Can[i][j]-'0';for(int k = 1;k < tmp;++k)CC[(k-1)*n+i][k*n+i] = 1;CC[(tmp-1)*n+i][j] = 1;}}B.h = B.l = n * 5;Mat ans = Pow(B,t);printf("%d",ans.A[s][f]);return 0;}


1 0
原创粉丝点击