bzoj1656

 

【题目描述】
现在有一片树林, 小 B 很想知道, 最少需要多少步能围绕树林走一圈, 最后回到起点. 他
能上下左右走,也能走对角线格子。
土地被分成 R 行 C 列(1≤R≤50,1≤C≤50),下面是一张样例的地图,其中“.”表示
小 B 可以走的空地,"X"表示树林,"*”表示起点。而小 B 走的最近的路己经特别地用“+”
表示出来。
. . . + . . .
. . + X + . .
. + X X X + .
. . + X X X +
. . + X . . +
. . . + + + *
题目保证,一定有合法解并且有且只有一片树林,树林一定是上下左右联通的。
【输入数据】
第 1 行输入 R 和 C,接下来 R 行 C 列表示一张地图。地图中的符号如题干所述。
【输出数据】
输出最少的步数。
【样例输入】
6 7
.......
...X...
..XXX..
...XXX.
...X...
......*
【样例输出】
13
【数据范围】
对于 40%的数据,R,C≤12
对于 60%的数据,R,C≤30
对于 100%的数据,R,C≤50

题解:啊我们一看就知道不能裸的bfs啊,于是考虑,能不能在某处设置一个分割线,把图分成两个部分。

于是我们就可以脑补到计算几何里面求点是否在多边形内部的那个办法,xjb做一下这题。。QAQ

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <stdio.h>
 4 #include <cmath>
 5 #include <string>
 6 #include <string.h>
 7 #include <numeric>
 8 #define gc getchar()
 9 #define REM main
10 using namespace std;
11 int n,m;
12 int dx[9]={0,-1, 1, 0, 0, -1, 1, -1, 1};
13 int dy[9]={0,0, 0, -1, 1, -1, -1, 1, 1};
14 int f[2][51][51]={};
15 int line[51][51]={};
16 struct node
17 {
18     int x,y,f;
19 }q[100000];
20 bool a[51][51]={};
21 int read()
22 {
23     int xxxx=0,fuh=1;char ch=gc;
24     while(!isdigit(ch)){
25         if(ch=='-')fuh=-1;
26         ch=gc;
27     }
28     while(isdigit(ch)){
29         xxxx=(xxxx<<3)+(xxxx<<1)+ch-'0';ch=gc;
30     }
31     return xxxx*fuh;
32 }
33 int REM()
34 {
35     cin.sync_with_stdio(false);
36     //freopen("grove.in","r",stdin);
37     //freopen("grove.out","w",stdout);
38     n=read();m=read();
39     int X,Y,x,y,i,j;
40     int flag=0;
41     for (i=1;i<=n;i++)
42       for (j=1;j<=m;j++)
43         {
44           char wwef=getchar(); 
45           while(wwef!='.'&&wwef!='X'&&wwef!='*') 
46             wwef=getchar();
47           if(wwef=='X') 
48             a[i][j]=1,x=i,y=j;
49           else 
50             if(wwef=='*') 
51               q[1].x=i,q[1].y=j,X=i,Y=j;
52         }
53     for (i=1;i<=n;i++)
54       if (i+x<=n)
55         line[i+x][y]=1;
56     int head=0,tail=1;
57     q[1].f=0;
58     /*for (i=1;i<=n;i++){
59       for (j=1;j<=m;j++)
60         cout<<line[i][j]<<" ";
61       cout<<endl;}*/
62     do
63       {
64           head++;
65           x=q[head].x;
66           y=q[head].y;
67           flag=q[head].f;
68           for (i=1;i<=8;i++)
69             {
70                 int fx,fy;
71                 fx=dx[i]+x;
72                 fy=dy[i]+y;
73                 if (fx<0 || fx>n || fy<0 || fy>m || a[fx][fy]) 
74               continue;
75             if (fy<=y && (line[x][y] || line[fx][fy]))
76               continue;
77             if(line[fx][fy] && !f[1][fx][fy]) 
78               { 
79                 f[1][fx][fy]=f[flag][x][y]+1;
80                 q[++tail].x=fx, q[tail].y=fy, q[tail].f=1;
81               }
82             else 
83               if(!f[flag][fx][fy]) 
84                 { 
85                    f[flag][fx][fy]=f[flag][x][y]+1;
86                    q[++tail].x=fx, q[tail].y=fy, q[tail].f=flag; 
87                 }
88           }
89       }while(head<=tail);
90     cout<<f[1][X][Y];
91     return 0;
92 }
我挽鲁智杖

 

posted @ 2016-09-29 10:17  yz12138  阅读(226)  评论(0编辑  收藏  举报