1. 程式人生 > >百練2812 惱人的青蛙

百練2812 惱人的青蛙

此題關鍵是將所有點排序後,遍歷每次確保被選中的兩個點是一條青蛙路徑上最先被踩踏的兩個水稻。

在遍歷點的過程中,要注意青蛙能夠從一側進入稻田,沿著直線一直跳,直到最後跳出稻田,如果青蛙連著跳了4個點,該條直線上的第5點還在稻田中,但是青蛙沒有踩踏,則該條路徑不合法,不能記錄青蛙當前最大的踩踏數是4,而應該記0。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;

bool vis[5005][5005]; //記錄對應座標是否被踩過, int型竟然TLE

struct Point{
    int x;
    int y;
}p[5005];

bool cmp(Point a,Point b)
{
    if(a.x==b.x)
        return a.y<b.y;
    return a.x<b.x;
}
int main()
{
    int R,C,n;
    scanf("%d%d",&R,&C);
    scanf("%d",&n);
    int a,b;
    memset(vis,0,sizeof(vis));
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&a,&b);
        p[i].x=a;
        p[i].y=b;
        vis[a][b]=true;
    }
    sort(p,p+n,cmp);
    int maxn=2;  //當前踩過的水稻的最大數目
    for(int i=0;i<n-2;i++)
    {
        for(int j=i+1;j<n-1;j++)
        {
            int dx=p[j].x-p[i].x;
            int dy=p[j].y-p[i].y;
            int x0=p[i].x-dx;
            int y0=p[i].y-dy;
            int x3=p[j].x+dx;
            int y3=p[j].y+dy;
            //保證i,j是最先被踩踏的兩個水稻
            if(x0>=1 && x0<=R && y0>=1 && y0<=C)
                continue;
            if(x3<1 || x3>R || y3<1 || y3>C) continue;
            if(!vis[x3][y3]) //無法構成一條三個踩踏點
                continue;
            int sum=2;
            //最後的出口一定是點不在範圍了,即青蛙一直走到盡頭跳出
            while(x3>=1 && x3<=R && y3>=1 && y3<=C)
            {
                if(vis[x3][y3])
                    sum++;
                else {sum=0; break;} //青蛙走這條路沒有跳出池塘,WA點
                x3+=dx;
                y3+=dy;
            }
            if(sum>maxn) maxn=sum;
        }
    }
    if(maxn==2) printf("0\n");
    else printf("%d\n",maxn);
    return 0;
}