POJ_1054_enum_讨厌的青蛙

讨厌的青蛙

From Coursera 北京大学 算法设计课程
题目类型:枚举
本题POJ链接:传送门

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>

using namespace std;

int r,c,n;
struct PLANT{
    int x,y;
};
PLANT plants[5001];
PLANT plant;
int searchPath(PLANT secPlant,int dX,int dY);

int main()
{
    freopen("D:/Studio/CPPProject/OJ/InputData/POJ_1054_enum.txt","r",stdin);
    int i,j,dX,dY,pX,pY,steps,max=2;
    //行数和列数,X方向是上下,Y方向是左右 
    scanf("%d %d",&r,&c);
    scanf("%d",&n);
    for(i = 0;i<n;i++)
        scanf("%d %d",&plants[i].x,&plants[i].y);
    //将水稻按X坐标从小到大排序,X坐标相同按Y从小到大排序 
    sort(plants,plants+n);
    for(i = 0;i<n-2;i++)
        for(j = i+1;j<n-1;j++)
        {
            dX = plants[j].x - plants[i].x;
            dY = plants[j].y - plants[i].y;
            pX = plants[i].x - dX;
            pY = plants[i].y - dY;
            if(pX<=r && pX>=1 && pY<=c && pY>=1 )
                continue;
                //第一点的前一点在稻田里,说明本次所选的第二点导致
                //的X方向步长不合理(太小)
            if(plants[i].x + (max-1)*dX > r)
                break;
                //X方向过早越界了,说明本次选的第二点不成立,说明换下一个点
                //点作为第二点,x方向步长只会更大,更不成立,所以本次选的第一点
                //必然不成立,那么取下一个点作为第一点再试
            pY = plants[i].y + (max-1)*dY;
            if(pY>c || pY<1)
                continue;
                //y方向过早越界了,应换一个点作为第二点再试
            steps = searchPath(plants[j],dX,dY);
            if(steps > max) max = steps;
        }
    if(max == 2) max=0;     
    printf("%d\n",max); 
}

bool operator <(const PLANT &p1,const PLANT &p2)
{
    if(p1.x == p2.x)
        return p1.y<p2.y;
    return p1.x < p2.x; 
} 

//判断从secPlant点开始,步长为dX,dY,那么最多能走几步
int searchPath(PLANT secPlant,int dX,int dY)
{
    PLANT plant;
    int steps;
    plant.x = secPlant.x + dX;
    plant.y = secPlant.y + dY;
    steps = 2;
    while(plant.x<=r && plant.x>=1 && plant.y<=c && plant.y>=1)
    {
        if(!binary_search(plants,plants+n,plant))
        {
            //每一步都必须踩到水稻才算合理,否则这就不是一条行走路径
            steps = 0;
            break;  
        }
        plant.x += dX;
        plant.y += dY;
        steps++;    
    }
    return steps;   
}   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值