[关闭]
@AkamemakA 2022-08-22T11:37:06.000000Z 字数 2147 阅读 194

Atcoder 题解

Atcoder Beginnner Contest 265 problem E 题解


题目链接:点我

题目大意

一个人初始在的位置。他有一个传送器。他会进行次操作,每次操作进行一下三种中的一种(当前他在的位置):

另外,在地图上有个点有障碍物。这个人不能传送到这些点上。

问这个人从初始点开始,经过次操作后能得到多少不同的路径。答案对取模。

第一行输入,第二行输入,接下来行,每行两个整数,表示障碍物的坐标。

样例输入1

  1. 2 2
  2. 1 1 1 2 1 3
  3. 1 2
  4. 2 2

样例输出1

  1. 5

样例解释1

有以下五条路径:

样例输入2

  1. 10 3
  2. -1000000000 -1000000000 1000000000 1000000000 -1000000000 1000000000
  3. -1000000000 -1000000000
  4. 1000000000 1000000000
  5. -1000000000 1000000000

样例输出2

  1. 0

样例输入3

  1. 300 0
  2. 0 0 1 0 0 1

样例输出3

  1. 292172978

数据范围


解析

本蒟蒻第一次考场拿下第五题!!!(纪念一下)

首先想到的是最最最暴力的,时间复杂度,(铁定能过)

一般对于这种数路径,又有模数的问题,很容易就想到

但这道题的地图是无限大的,所以不可能枚举点。然而我们发现,如果我们确定了三种操作的次数,那么这个人最终到达的点也可以被确定。因此,我们不妨枚举三个操作所用的次数,这样就可以知道当前这个人在那个点,如下:

  1. //三层枚举
  2. int gx=i*A+j*C+k*E;
  3. int gy=i*B+j*D+k*F;

定义表示这个人走到表示的点处的方案数。

然后,这个点只可能由三种状态转移而来,即。用将它们累加。

如果说这个点是一个障碍物,那么.

时,将答案累加即可。

比较有趣的一点是,这道题的时间限制是,众所周知,测评器能跑次循环,而,刚好是的时限。本蒟蒻也是从这里受到了启发。

好了,话不多说,上代码:


代码实现:

  1. #include<iostream>
  2. #include<map>
  3. using namespace std;
  4. #define int long long
  5. const int N=305,mod=998244353,base=1e9;
  6. int n,m,a,b,c,d,e,F;
  7. int f[N][N][N],ans;
  8. int x,y;
  9. map<int,bool>mp;
  10. inline int get_point(int x,int y){
  11. return (x-1)*base+y;
  12. }
  13. signed main(){
  14. cin>>n>>m>>a>>b>>c>>d>>e>>F;
  15. for(int i=1;i<=m;i++) cin>>x>>y,mp[get_point(x,y)]=1;//坐标很大,我们可以将二维坐标一维化,然后用map存储
  16. f[0][0][0]=1;//初始在(0,0)的位置,所以
  17. for(int i=0;i<=n;i++)
  18. for(int j=0;j<=n;j++){
  19. if(i+j>n) break;
  20. for(int k=0;k<=n;k++){
  21. if(i+j+k>n) break; //玄学优化
  22. if(i==0&&j==0&&k==0) continue; //起始点不用更新
  23. int gx=i*a+j*c+k*e;
  24. int gy=i*b+j*d+k*F;
  25. if(mp[get_point(gx,gy)]) {f[i][j][k]=0;continue;} //障碍物
  26. if(i) f[i][j][k]=(f[i][j][k]+f[i-1][j][k])%mod;
  27. if(j) f[i][j][k]=(f[i][j][k]+f[i][j-1][k])%mod;
  28. if(k) f[i][j][k]=(f[i][j][k]+f[i][j][k-1])%mod;
  29. //一定要注意是否为0,不然数组可能会越界
  30. if(i+j+k==n) ans=(ans+f[i][j][k])%mod;
  31. }
  32. }
  33. cout<<ans;
  34. //跑出来刚好2700ms,神不神奇呢
  35. }

完结撒花~~~

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注