枚举之讨厌的青蛙

来源:互联网 发布:餐厅成本核算软件 编辑:程序博客网 时间:2024/05/17 08:19

题目大意:有青蛙每天晚上都去稻田里会踩踏稻谷,知道青蛙的每次跳跃都是等间隔的,并且沿直线跳跃。现在农夫第二天早上根据被踩踏的稻谷,希望找出那只对稻田伤害最大的青蛙,也就是那只青蛙在一条直线上踩踏了最多的稻谷。最后求得的路径水稻踩踏数必定大于等于3,否则则将踩踏数记为0.

输入:稻田的行数和列数 接下来输入N 再接下来的N行表示被踩踏的稻谷的坐标(横坐标和纵坐标)

输出:整个稻田里位于一条直线上的被踩踏到的稻谷的最大值

测试用例:

6 7

14

2 1

6 6

4 2

2 5

2 6

2 7

3 4

6 1

6 2

2 3

6 3

6 4

6 5

6 7

总体思路:因为青蛙总是沿直线跳跃,因此只要确定了青蛙最先踩踏的第一点和第二点,就可以得到跳跃间隙,于是就可以确定青蛙在稻田里跳跃的整条路径

于是可以创建一个类(该类实现了Comparable接口)用来保存青蛙每次踩踏的位置,再将这些位置保存在集合中并对他们进行排序,这里首先用TreeSet存储路径,这样就在存储的过程中已经对踩踏点进行了排序,然后再将TreeSet集合中的所有元素转存在ArrayList集合中,这样方便通过下标来取出ArrayList集合中的元素。

确定了存储方式之后,就要确定如何排除不满足条件的路径。在ArrayList集合中,依照下标依次取出两个位置作为青蛙的第一个位置和第二个位置,但是这两个位置必须满足如下条件:

1、第一个位置减去间隔必须在稻田以外,如果在稻田以内则说明第二点离第一点过近,第二点选取不合理

2、如果第一个位置加上(已知的最大踩踏数-1)*步长已经在稻田外,说明青蛙过早地出了稻田,说明第一点选取不合理,因为第二点越往后,与第一点的距离只会越来越大,所以是第一点没选好。

上代码:

package enumeration;import java.util.ArrayList;import java.util.Comparator;import java.util.Iterator;import java.util.Scanner;import java.util.TreeSet;public class Frogs {public static int max=2;public static int line;public static int column;public static ArrayList<rice> al;public static void main(String args[]) {Scanner scan=new Scanner(System.in);TreeSet<rice> ts=new TreeSet<rice>();//记录水稻田的行数和列数line=scan.nextInt();column=scan.nextInt();//记录被踩踏的水稻数目int N=scan.nextInt();//输入并记录被踩踏的水稻的坐标for(int i=0;i<N;i++) {int x=scan.nextInt();int y=scan.nextInt();ts.add(new rice(x,y));}//创建arrayList集合,将TreeSet中的元素传入进去,便于以数组的方式对元素进行取出al=new ArrayList<rice>();Iterator<rice> it=ts.iterator();while(it.hasNext()) {al.add(it.next());}//以上,被踩踏的稻子就全部都存储到al集合中去了//现在开始枚举青蛙踩踏的前两个点int size=al.size();for(int i=0;i<size-1;i++) {for(int j=i+1;j<size;j++) {int x1=al.get(i).getX();int y1=al.get(i).getY();int x2=al.get(j).getX();int y2=al.get(j).getY();int dx=x2-x1;int dy=y2-y1;//如果第一个点减去步长还在稻田内说明第二点选取失败if(x1-dx>=1&&y1-dy>=1)continue;if(x1+(max-1)*dx>line)break;if(y1+(max-1)*dy>column)break;int step=steps(x1,y1,dx,dy);if(step>max)max=step;}}if(max==2)max=0;System.out.println(max);}public static int steps(int x1,int y1,int dx,int dy) {int step=0;while(x1>=1&&x1<=line&&y1>=1&&y1<=column) {if(!isfall(x1,y1)) {step=0;break;}step++;x1+=dx;y1+=dy;}return step;}public static boolean isfall(int x1,int y1) {boolean flag=false;for(int i=0;i<al.size();i++) {int x=al.get(i).getX();int y=al.get(i).getY();if(x1==x&&y1==y) {flag=true;break;}}return flag;}}class rice implements Comparable{private int x;private int y;public rice(int x, int y) {super();this.x = x;this.y = y;}public int getX() {return x;}public int getY() {return y;}public int compareTo(Object o) {rice r=(rice)o;if(r.x>=this.x) {if(r.x>this.x)return -1;else {if(r.y>this.y)return -1;elsereturn 1;}}elsereturn 1;}}