4月8日

poj3194

题意:这题的题意比较难理解,我理解了半天,题意是给定一个n*n的矩阵,矩阵里面有n*n个元素,问每个元素是否都能组成n连块,若可以输出good,否则输出wrong,输出比较奇怪,是给的是每个点的两个坐标,这个点的值为所在行号

分析:读懂题以后这题不难,直接dfs,统计连块的个数即可

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <vector>
 6 #include <algorithm>
 7 #include <set>
 8 #include <map>
 9 #include <bitset>
10 #include <cmath>
11 #include <queue>
12 #include <stack>
13 using namespace std;
14 const int maxn=120;
15 int mp[maxn][maxn];
16 int vis[maxn][maxn];
17 int n;
18 int cnt;
19 int dx[]={-1,1,0,0},dy[]={0,0,1,-1};
20 void dfs(int x,int y,int k)
21 {
22     vis[x][y]=1;
23     for(int i=0;i<4;i++)
24     {
25         int nx=x+dx[i];
26         int ny=y+dy[i];
27         if(nx>=0&&nx<n&&ny>=0&&ny<n&&!vis[nx][ny]){
28             if(mp[nx][ny]==k)
29             {
30                 cnt++;
31                 dfs(nx,ny,k);
32             }
33         }
34     }
35 }
36 int main()
37 {
38     while(cin>>n)
39     {
40         if(n==0)  break;
41         memset(mp,0,sizeof(mp));
42         for(int i=1;i<n;i++)
43             for(int j=0;j<n;j++)
44             {
45                 int x,y;
46                 scanf("%d%d",&x,&y);
47                 mp[x-1][y-1]=i;
48             }
49         memset(vis,0,sizeof(vis));
50         int num=0;
51         for(int k=1;k<n;k++)
52         {
53             bool flag=false;
54             for(int i=0;i<n;i++)
55             {
56                 for(int j=0;j<n;j++)
57                 {
58                     cnt=1;
59                     if(!vis[i][j]&&mp[i][j]==k)
60                     {
61                          dfs(i,j,k);
62                          if(cnt==n) num++;
63                     }
64                 }
65             }
66         }
67         if(num==n-1) cout<<"good"<<endl;
68         else cout<<"wrong"<<endl;
69     }
70     return 0;
71 }
View Code

 HDU1010

题意:给定一个迷宫的起点和终点,x表示不能走,.表示可以走,问能否正好在t时间逃出

分析:非常好的dfs+剪枝,开始看错题目,以为是否能在t内逃出,直接bfs最短路,wa,接着再次看题,然后拍了一份dfs,发现TLE,最后在网上看了别人的思路,这题要进行奇偶剪枝。abs(sx-gx)+abs(sy-gy)表示两点之间的距离,t-step代表还要经过多少步可以到达。因为网格中任意两条可行路径的长度必定是同奇偶的,故这二者奇偶性必须相同。同时若t-step比abs(sx-gx)+abs(sy-gy)还小,表示t秒到不了,剪枝。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <vector>
 6 #include <algorithm>
 7 #include <set>
 8 #include <map>
 9 #include <bitset>
10 #include <cmath>
11 #include <queue>
12 #include <stack>
13 using namespace std;
14 const int maxn=20;
15 char s[maxn][maxn];
16 int vis[maxn][maxn];
17 int n,m,t;
18 int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
19 int flag;
20 void dfs(int sx,int sy,int gx,int gy,int step)
21 {
22     if(flag)  return;
23     if(sx==gx&&sy==gy&&step==t){
24         flag=1; return;
25     }
26     int temp=t-step-abs(sx-gx)-abs(sy-gy);
27     if(temp<0||temp%2!=0)  return;
28     for(int i=0;i<4;i++)
29     {
30         int nx=sx+dx[i];
31         int ny=sy+dy[i];
32         if(nx>=0&&nx<n&&ny>=0&&ny<m&&!vis[nx][ny])
33         {
34             if(s[nx][ny]!='X'){
35                 vis[nx][ny]=1;
36                 dfs(nx,ny,gx,gy,step+1);
37                 vis[nx][ny]=0;
38             }
39         }
40     }
41 }
42 int main()
43 {
44     while(cin>>n>>m>>t)
45     {
46         if(n+m+t==0)  break;
47         for(int i=0;i<n;i++)
48             for(int j=0;j<m;j++)
49                 cin>>s[i][j];
50         memset(vis,0,sizeof(vis));
51         int sx,sy,gx,gy;
52         for(int i=0;i<n;i++)
53             for(int j=0;j<m;j++)
54             {
55                 if(s[i][j]=='S'){
56                     sx=i,sy=j;
57                 }else if(s[i][j]=='D'){
58                     gx=i,gy=j;
59                 }
60             }
61         flag=0;
62         vis[sx][sy]=1;
63         dfs(sx,sy,gx,gy,0);
64         if(flag) cout<<"YES"<<endl;
65         else  cout<<"NO"<<endl;
66     }
67     return 0;
68 }
View Code
原文地址:https://www.cnblogs.com/wolf940509/p/5367085.html