A题:可以当作BFS板子做,切记这题不能用DFS,DFS会被卡的很惨,BFS的最差时间复杂度是n^3。
答主比赛的时候一直MLE,因为是在出队列的时候标记vis数组,这个一定要进队列前标记,不然会进去很多不必要的到指爆内存
#include<bits/stdc++.h> using namespace std; typedef long long ll; inline ll read(){ ll s=0,f=1;char c=getchar(); while(c<'0'||c>'9'){ if(c=='-')f=-1; if(c=='.'||c=='*')return c;//修改了下快读可以返回字符 c=getchar(); } while(c>='0'&&c<='9'){ s=(s<<1)+(s<<3)+(c^48);c=getchar(); } return f*s; } int vis[111][111][111],n; int dx[7]={0,1,-1,0,0,0,0},dy[7]={0,0,0,1,-1,0,0},dz[7]={0,0,0,0,0,1,-1}; struct node{ int x,y,z,dis; }; int bfs(){ queue<node>q; q.push((node){1,1,1,1}); while(!q.empty()){ int x=q.front().x,y=q.front().y,z=q.front().z,d=q.front().dis; //一开始vis[x][y][z]=true放在这,疯狂MLE找不到错QAQ if(x==n&&y==n&&z==n)return d; q.pop(); for(int i=1;i<=6;i++){ int X=x+dx[i],Y=y+dy[i],Z=z+dz[i]; if(vis[X][Y][Z]||X<1||Y<1||Z<1||X>n||Y>n||Z>n)continue; vis[X][Y][Z]=true; q.push((node){x+dx[i],y+dy[i],z+dz[i],d+1}); } } return -1; } int main(){ n=read(); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ vis[i][j][k]=(read()=='*'); } } } cout<<bfs()<<endl; return 0; }
B题:DP练手题。
我们只能通过从左边的点和下面的点到达当前的点。所以状态转移方程就出来了a[i][j]=a[i-1][j]+a[i][j-1],注意下如果是障碍物的话就不能转移状态。
#include<bits/stdc++.h> using namespace std; typedef long long ll; inline ll read(){ ll s=0,f=1;char c=getchar(); while(c<'0'||c>'9'){ if(c=='-')f=-1;c=getchar(); } while(c>='0'&&c<='9'){ s=(s<<1)+(s<<3)+(c^48);c=getchar(); } return f*s; } ll a[3333][3333]; const int mod=2333; int main(){ ll n=read(),m=read(); for(int i=n;i>=1;i--){//这里注意下题目是说左下到右上,所以我们把外面这层循环反过来就行了,这样就会变成左上到右下。 for(int j=1;j<=m;j++){ a[i][j]=!read(); } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i][j]) a[i][j]=(a[i-1][j]+a[i][j-1])%mod; a[1][1]=1; } } cout<<a[n][m]<<endl; }
D题:模拟题
这题如果你会python的话很简单,只需要emmmmmmmmmmm
print(input()%10000)