DFS
i.这是我的地盘
题意:寻找一个被围住‘X’的区域'O',把它变成'X',如果有O与边界相连,那一块不算
思路:从(0,0)开始染色,伟大的0,0点啊!
1 #include <bits/stdc++.h> 2 using namespace std; 3 int a[1024][1024]; 4 char b[1024][1024]; 5 int dx[5]={0,-1,1,0,0}; 6 int dy[5]={0,0,0,-1,1}; 7 int n,m,i,j; 8 void dfs(int p,int q){ 9 if (p<0||p>n+1||q<0||q>m+1||a[p][q]!=0) return; 10 a[p][q]=1;//染色 11 for (int i=1;i<=4;i++) dfs(p+dx[i],q+dy[i]); 12 } 13 int main(){ 14 int t; 15 cin >> t; 16 while(t--){ 17 cin >> n >> m; 18 memset(a, 0, sizeof(a)); 19 for (i=1;i<=n;i++) 20 for (j=1;j<=m;j++){ 21 cin>>b[i][j]; 22 if (b[i][j]=='O') a[i][j]=0; 23 else a[i][j]=2; 24 } 25 dfs(0,0); 26 for (i=1;i<=n;i++){ 27 for (j=1;j<=m;j++) 28 if (a[i][j]==0) cout<<"X"; 29 else cout<<b[i][j]; 30 cout << '\n'; 31 } 32 } 33 system("pause"); 34 return 0; 35 }
ii.jumping on walls(CF)
题意:
有左右两面墙,从起点出发,X表示危险,-表示安全
有三个操作:沿墙向下1m,向上1m,向对面墙跳h米
同时有水位上升
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int N=1e5+200; 5 6 int n,k; 7 char a[2][N]; 8 bool b[2][N]; 9 10 bool dfs(bool side,int h,int step){//side代表左右两边墙 11 if (h>n)//jump out of canyon 12 return 1; 13 if (b[side][h]||a[side][h]=='X'||h<step)//h<step 从大峡谷(ノ`Д)ノ粗去了 14 return 0; 15 16 b[side][h]=1;//走过了的点 17 return dfs(side^1,h+k,step+1)||dfs(side,h-1,step+1)||dfs(side,h+1,step+1);//顺序很重要,先h+k 18 } 19 int main() 20 { 21 22 ios_base::sync_with_stdio(0); 23 cin.tie(0); 24 cout.tie(0);//为什么对这三行情有独钟呢?当然是~~~(省略) 25 cin>>n>>k; 26 27 scanf("%s %s",a[0]+1,a[1]+1);//注意这个输入方法;用于输入两行二维字符数组很合适, 28 //或者: 29 //for(int i=0;i<2;i++){ 30 // for(int j=1;j<=n;j++){ 31 // a[i][j]=getchar()=='X'; 32 //} 33 //for(;getchar()^'/n';) 34 //} 35 36 if(dfs(0,1,1))// 37 cout<<"YES"; 38 else 39 cout<<"NO"; 40 41 return 0; 42 }
III.棋盘问题
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 typedef long long ll; 6 const int N=1e9; 7 int n,k,ans; 8 string a[9];//map 9 bool vis[9];//column 10 void dfs(int x,int step){//current line 11 if(step==k){ans++;return;} 12 else{ 13 for(int j=x;j<n;j++){ 14 for(int i=0;i<n;i++){ 15 if(a[j][i]=='#'&&!vis[i]){ 16 vis[i]=1; 17 dfs(j+1,step+1); 18 vis[i]=0; 19 } 20 } 21 } 22 } 23 } 24 int main(){ 25 ios_base::sync_with_stdio(0); 26 cin.tie(0); 27 cout.tie(0); 28 29 while(cin>>n>>k){ 30 if(n==-1)return 0; 31 32 for(int i=0;i<n;i++)cin>>a[i]; 33 34 memset(vis,0,sizeof(vis)); 35 ans=0; 36 37 dfs(0,0); 38 39 cout<<ans<<endl; 40 } 41 return 0; 42 }
DFS+并查集
01迷宫luogu
1 #include<iostream> 2 using namespace std; 3 #define maxn 1000005 4 int f[maxn], h[maxn], n; 5 int st[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; 6 char s[1005][1005]; 7 //模板 8 int find(int x){return f[x]==x?x:f[x]=find(f[x]);} 9 void unionn(int x,int y){ 10 int r1=find(x),r2=find(y); 11 if(r1!=r2)h[r1]+=h[r2],f[r2]=f[r1]; 12 } 13 //模板 14 int dfs(int x,int y){//功能:寻找(x,y)的起始位置,并且进行同一联通块的合并 15 int t = x * n + y; 16 if(f[t]!=-1)return find(t); 17 f[t]=t,h[t]=1;//构造映射 18 for(int k=0;k<4;k++){ 19 int i=x+st[k][0],j=y+st[k][1]; 20 if(i>=0&&i<=n-1&&j>=0&&j<=n-1&&s[x][y]!=s[i][j]) 21 unionn(t,dfs(i,j));//将点(x,y)与点(i,j)合并 22 } 23 return find(t); 24 } 25 int main(){ 26 int t,i,j; 27 scanf("%d%d", &n, &t); 28 memset(f, -1, 4 * n * n); 29 for(int i=0;i<n;i++) 30 scanf("%s", s[i]); 31 while(t--){ 32 scanf("%d%d", &i, &j); 33 printf("%d\n", h[dfs(i - 1, j - 1)]);//查找该点,注意-1 34 } 35 return 0; 36 }
BFS
i.用水填坑
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 struct node{int x,y,h;}; 5 bool operator<(node a,node b){return a.h>b.h;} 6 int n, m, a[1024][1024], vis[1024][1024], ans; 7 int dirx[4]={0,0,1,-1},diry[4]={1,-1,0,0}; 8 priority_queue<node>q; 9 int32_t main(){ 10 scanf("%lld%lld",&n,&m); 11 for(int i=1;i<=n;++i) 12 for(int j=1;j<=m;++j)scanf("%d",&a[i][j]); 13 for(int i=1;i<=n;++i) 14 for(int j=1;j<=m;++j) 15 if(i==1||j==1||i==n||j==m) 16 q.push((node){i,j,a[i][j]}),vis[i][j]=1; 17 while(!q.empty()){ 18 node t=q.top();q.pop(); 19 for(int k=0;k<4;k++){ 20 int x = t.x + dirx[k], y = t.y + diry[k], h = t.h; 21 if(x<1||x>n||y<1||y>m||vis[x][y])continue; 22 vis[x][y]=1; 23 if(a[x][y]<h)ans+=h-a[x][y],a[x][y]=h; 24 q.push((node){x,y,a[x][y]}); 25 } 26 } 27 printf("%lld",ans); 28 }
ZOJ4020 Traffic Light
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 const int maxn = 1e5 + 10; 5 const int inf = 999999999; 6 #define pb push_back 7 #define scan(n) scanf("%lld", &n) 8 struct node{ 9 int x, y, dis; 10 }; 11 vector<int> a[maxn]; 12 vector<bool> vis[maxn]; 13 int n, m, T, num, ex, sy, sx, ey; 14 int32_t main(){ 15 scan(T); 16 while(T--){ 17 scan(n); 18 scan(m); 19 for (int i = 1; i <= n;i++){ 20 a[i].clear(); 21 vis[i].clear(); 22 a[i].pb(3); 23 vis[i].pb(false); 24 } 25 for (int i = 1; i <= n;i++) 26 for (int j = 1; j <= m;j++){ 27 scan(num); 28 a[i].pb(num); 29 vis[i].pb(false); 30 } 31 scanf("%lld%lld%lld%lld", &sx, &sy, &ex, &ey); 32 queue<node>q; 33 q.push((node){sx, sy,0}); 34 int x, y, dis; 35 int ans=inf; 36 while(!q.empty()){ 37 node t = q.front(); 38 q.pop(); 39 x = t.x, y = t.y, dis = t.dis; 40 if(x>n||x<1||y>m||y<1||vis[x][y]) 41 continue; 42 if(x==ex&&y==ey){ 43 ans = dis; 44 break; 45 } 46 vis[x][y] = true; 47 if((a[x][y]%2+dis%2)%2==1){ 48 q.push((node){x, y - 1,dis+1}); 49 q.push((node){x, y + 1,dis+1}); 50 } 51 else{ 52 q.push((node){x-1, y,dis+1}); 53 q.push((node){x+1, y,dis+1}); 54 } 55 //cnt++; 56 } 57 if(ans==inf) 58 ans = -1; 59 printf("%lld\n", ans); 60 } 61 //system("pause"); 62 }