WEEK 2
山
-
如何判断是否为一座山:
将搜索过的山改为0,直到四周出现一个全为0的点,即为边界
-
dfs
#include<iostream> using namespace std; int a[2005][2005]; int ans=0; int m,n; void dfs(int x,int y) { if(x<=0||y<=0||x>m||y>n||a[x][y]==0) return; a[x][y]=0; dfs(x-1,y); dfs(x+1,y); dfs(x,y+1); dfs(x,y-1); } //重点是判断的条件 int main() { cin>>m>>n; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { cin>>a[i][j]; } } //枚举每一个点 for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { if(a[i][j]==1) { dfs(i,j);//向四周搜索 ans++; } } } cout<<ans; return 0; }
-
跳跃
- 终点可能不止一个:直接判断值是否为0【不可以通过记录终点的方法】
- 直接搜索
#include<iostream> using namespace std; const int maxn=5*1e5; int n,a[maxn]; int vis[maxn]; int s[2]={-1,1}; int flag=0; void dfs(int x) { //判断边界 if(a[x]==0||x>n-1||x<0) { //找到终点 if(a[x]==0) flag=1; return; } //枚举可能的操作 for(int i=0;i<2;i++) { int nx=x+s[i]*a[x]; if(vis[nx]==0&&nx>=0&&nx<n) { vis[nx]=1; dfs(nx); vis[nx]=0; //回溯 } } } int main() { cin>>n; for(int i=0;i<n;i++) { cin>>a[i]; } int start; cin>>start; //从起点开始dfs dfs(start); vis[start]=1; if(flag==0) cout<<"False"; else cout<<"True"; return 0; }
-
最长光路
- 题目不难,代码实现小心细节
- 搜索时:
- C:直接返回
- \或者/ 需要改变方向【每个状态:需要记录x、y和方向】
- 每走一步加一下
- 难点:如何判断是否成环:是否通过同一个方向走过
- 启发:状态 表示与标记是否走过应该是相同的维度
#include<bits/stdc++.h> using namespace std; int vis[505][505][5]; int flag=0; int n,m; int ans=0; char a[505][505]; void dfs(int x, int y, int c) { //边界/无法穿过 if(x<0||x>=n||y<0||y>=m||a[x][y]=='C') return; //成环 if(vis[x][y][c]==1) { flag=1; return; } //每走一步 标记 ans++; vis[x][y][c]=1; //下一步的位置 int nx=x,ny=y; if(c==1) nx--; if(c==2) ny++; if(c==3) nx++; if(c==4) ny--; //如果碰到镜子 if(a[nx][ny]=='\\') { if(c==1) c=4; else if(c==4) c=1; else if(c==3) c=2; else if(c==2) c=3; } if(a[nx][ny]=='/') { if(c==3) c=4; else if(c==4) c=3; else if(c==1) c=2; else if(c==2) c=1; } //搜索下一步 if(nx>=0&&nx<n&&ny>=0&&ny<m) dfs(nx,ny,c); else return; } //传入方向!:以数字穿 int main() { cin>>n>>m; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cin>>a[i][j]; } } int sx,sy; cin>>sx>>sy; sx--;sy--; int max=0; int k; for(int i=1;i<=4;i++) { dfs(sx,sy,i);//搜索每一个方向 if(flag==1){k=i;break;} memset(vis,0,sizeof(vis));//更新 if(max<ans&&flag==0)//存最大值 { max=ans; k=i; } ans=0; } if(k==1) cout<<"U"; if(k==2) cout<<"R"; if(k==3) cout<<"D"; if(k==4) cout<<"L"; cout<<endl; if(flag==1) cout<<"COOL"; else cout<<max; return 0; }
-
回文数
- 可以得知为9位数
- 只需枚举前5位数
- 判断大小
#include<iostream> using namespace std; int main() { int n; cin>>n; int sum=0; const int maxn=1e8; int ans=0; for(int i=1;i<=9;i++) { for(int j=0;j<=9;j++) { for(int k=0;k<=9;k++) { for(int l=0;l<=9;l++) { for(int m=0;m<=9;m++) { ans=i*maxn+j*maxn/10+k*maxn/100+l*maxn/1000+m*10000+i+j*10+k*100+l*1000;//小心每一位的位数 if(ans<=n) sum++; } } } } } cout<<sum<<endl; return 0; }