讨厌的青蛙
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;
}