• bzoj 1297 [SCOI2009]迷路


    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1297

    用emacs打的第二道题目!

    其实很简单。就是拆点。然后就和poj3613一样了。

    把边拆成权值个数的点。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int N=1015,mod=2009;
    int n,tot,T;
    struct Matrix{
      int a[N][N];
      Matrix(){memset(a,0,sizeof a);}
      Matrix operator* (const Matrix &b)const
      {
        Matrix c;
        for(int i=0;i<=tot;i++)
          for(int k=0;k<=tot;k++)
        for(int j=0;j<=tot;j++)
          (c.a[i][j]+=(a[i][k]*b.a[k][j]))%=mod;
        return c;
      }
    }r,ans;
    int main()
    {
      scanf("%d%d",&n,&T);tot=n-1;int x;
      for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
          {
        scanf("%1d",&x);
        if(!x)continue;
        if(x==1){r.a[i][j]=1;continue;}
        r.a[i][++tot]=1;
        for(int k=2;k<x;k++)r.a[tot][++tot]=1;
        r.a[tot][j]=1;
          }
    
      ans.a[0][0]=1;
      while(T)
        {
          if(T&1)ans=ans*r;
          r=r*r;T>>=1;
        }
      printf("%d
    ",ans.a[0][n-1]);
      return 0;
    }
    View Code

    但是WA了。可能是数组太大,爆栈了什么的。

    其实应该是把点拆成9个点,自己向自己的第一个点走的距离表示连向自己的边的权值。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int mod=2009,base=9;
    int n,tot,T;
    struct Matrix{
      int a[95][95];
      Matrix(){memset(a,0,sizeof a);}
      Matrix operator * (const Matrix &b)const
      {
        Matrix c;
        for(int i=1;i<=tot;i++)
          for(int k=1;k<=tot;k++)
        for(int j=1;j<=tot;j++)
          (c.a[i][j]+=a[i][k]*b.a[k][j])%=mod;
        return c;
      }
    }ans,r;
    int main()
    {
      scanf("%d%d",&n,&T);int x;tot=n*base;
      for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
          {
        scanf("%1d",&x);if(!x)continue;
        r.a[i*base+1][j*base+x]=1;
          }
      ans.a[1][1]=1;
      for(int i=tot;i;i--)
        if((i-2)/base==(i-1)/base)
          r.a[i][i-1]=1;
      while(T)
        {
          if(T&1)ans=ans*r;
          r=r*r;T>>=1;
        }
      printf("%d
    ",ans.a[1][(n-1)*base+1]);
      return 0;
    }
  • 相关阅读:
    关于视图的说明和设计
    关于REST风格API的设计
    关于 Linux 操作
    文件删除
    文件写入有读取
    生成器,迭代器
    Linux防火墙相关命令
    Linux下安装Maven
    Linux下安装Nginx
    Word相关知识点
  • 原文地址:https://www.cnblogs.com/Narh/p/9254520.html
Copyright © 2020-2023  润新知