• 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 }
    我挽鲁智杖
    Rem is my wife!(。・`ω´・)
  • 相关阅读:
    已设定选项readonly请加!强制执行
    Linux下NVIDIA显卡驱动安装方法
    C#使用MiniDump导出内存快照MiniDumper
    一些陈旧的注册表垃圾清理脚本:注册表冗余数据清理.reg
    脚本精灵一些脚本
    本地安装SonarQube Community8.1社区版进行代码质量管控
    spring redistemplate中使用setHashValueSerializer的设置hash值序列化方法
    spring-core-5.0.6.RELEASE-sources.jar中java源代码不全
    lombok插件/slf4j中字符串格式化
    light4j/light-4j一个轻量级的低延时、高吞吐量、内存占用量小的API平台
  • 原文地址:https://www.cnblogs.com/yz12138/p/5918918.html
Copyright © 2020-2023  润新知