1 条题解

  • 0
    @ 2025-8-24 21:45:00

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Limit
    技不如人

    搬运于2025-08-24 21:45:00,当前版本为作者最后更新于2020-01-08 15:27:14,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    USACO的题目,感觉还是挺神奇的.

    • 前置芝士

    1.DFS(BFS)遍历:用来搜索(因为DFS好写,本文以DFS为准还不是因为作者懒) 2.STL中的set(map)的基本用法:数据很大,不能直接存.

    • 具体做法

    因为不能把草堆围起来造成的周长记录起来所以不能再草堆中搜索,需要再这个草堆外面绕着搜索这样就不会将内部的周长记录下来了.

    在这里插入图片描述

    如这样一张图它的周长是(红色部分):

    在这里插入图片描述

    于是需要找到一个在最外边的点,可以发现最上方的那个点的就十分合适,搜索的位置(蓝色部分)

    在这里插入图片描述

    从最上方开始搜,如果搜到了草就answer++,return. 但是这样搜的时候如果一直往外跑就会直接炸掉,所以必须不能有这种情况,可以发现对于每一个蓝色位置的八个方向的一格处至少有一个草堆,于是如果没有草堆就直接退出.

    • 代码

    #include<bits/stdc++.h>
    #define rap(i,first,last) for(int i=first;i<=last;++i)
    using namespace std;
    const int move_x[9]={233,0,0,1,-1,1,1,-1,-1};
    const int move_y[9]={233,1,-1,0,0,1,-1,1,-1};
    set<pair<int,int> >_map;//用来记录这张图
    set<pair<int,int> >visit;//用来判断这个位置有没有走过
    int N,fx=-1,fy,answer=0;
    bool OutSide(int x,int y)//判断八个方向上有没有草堆
    {
    	rap(i,1,8)
    	if(_map.count(make_pair(x+move_x[i],y+move_y[i])))return 0;//有就返回0
    	return 1;//没有返回1
    }
    void DFS(int x,int y)//DFS
    {
    	if(_map.count(make_pair(x,y)))//如果这个位置是草堆就answer++,return
    	{
    		answer++;
    		return;
    	}
    	if(visit.count(make_pair(x,y)))return;//走过了就不能在走了
    	visit.insert(make_pair(x,y));//记录这个位置走过
    	if(OutSide(x,y))return;//如果八个方向上没有草堆则return
    	rap(i,1,4)//向四个方向搜索
    	DFS(x+move_x[i],y+move_y[i]);
    }
    int main()
    {
    	scanf("%d",&N);
    	int x,y;
    	rap(i,1,N)
    	{
    		scanf("%d%d",&x,&y);
    		_map.insert(make_pair(x,y));//地图中这个位置有草堆
    		if(x>fx)
    		{
    			fx=x;
    			fy=y;
    		}
    	}
    	DFS(fx+1,fy);//最上方那个点上方的那个点开始搜索
    	printf("%d",answer);//输出answer
    	return 0;
    }
    
    • 1

    信息

    ID
    2136
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者