搜索

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 }

 

转载于:https://www.cnblogs.com/guaguastandup/p/10628282.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值