首页 > 试题广场 >

射击游戏

[编程题]射击游戏
  • 热度指数:2799 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
小易正在玩一款新出的射击游戏,这个射击游戏在一个二维平面进行,小易在坐标原点(0,0),平面上有n只怪物,每个怪物有所在的坐标(x[i], y[i])。小易进行一次射击会把x轴和y轴上(包含坐标原点)的怪物一次性消灭。
小易是这个游戏的VIP玩家,他拥有两项特权操作:
1、让平面内的所有怪物同时向任意同一方向移动任意同一距离
2、让平面内的所有怪物同时对于小易(0,0)旋转任意同一角度
小易要进行一次射击。小易在进行射击前,可以使用这两项特权操作任意次。
小易想知道在他射击的时候最多可以同时消灭多少只怪物,请你帮帮小易。

如样例所示:

所有点对于坐标原点(0,0)顺时针或者逆时针旋转45°,可以让所有点都在坐标轴上,所以5个怪物都可以消灭。

输入描述:
输入包括三行。
第一行中有一个正整数n(1 ≤ n ≤ 50),表示平面内的怪物数量。
第二行包括n个整数x[i](-1,000,000 ≤ x[i] ≤ 1,000,000),表示每只怪物所在坐标的横坐标,以空格分割。
第二行包括n个整数y[i](-1,000,000 ≤ y[i] ≤ 1,000,000),表示每只怪物所在坐标的纵坐标,以空格分割。


输出描述:
输出一个整数表示小易最多能消灭多少只怪物。
示例1

输入

5
0 -1 1 1 -1
0 -1 -1 1 1

输出

5
 
/**
 * 解题思路: 点不变,坐标系旋转,看最多能有多少点在坐标系上;
 * 
 * @author symfony
 *
 */
public class Demo7 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        int[] x = new int[num];
        int[] y = new int[num];
        for (int i = 0; i < num; i++) {
            x[i] = sc.nextInt();
        }
        for (int i = 0; i < num; i++) {
            y[i] = sc.nextInt();
        }
        if (num <= 3) {
            // 三点构成一个坐标系,直接返回
            System.out.println(num);
            return;
        }
        int max = 0;
        for (int i = 0; i < num; i++) {
            for (int j = i + 1; j < num; j++) {
                // 此时取两点 i,j; 坐标为(x[i],y[i]),(x[j],y[j])
                // rp 记录直线i,j上的点的个数; 开始就有i,j两点,所以rp=2;
                int rp = 2;
                for (int s = 0; s < num; s++) {
                    if (s != i && s != j) {
                        if ((x[s] - x[i]) * (y[s] - y[j]) == (x[s] - x[j]) * (y[s] - y[i])) {
                            // s点和i,j在同一条直线上
                            rp++;
                        }
                    }
                }
                if (rp == num || rp == (num - 1)) {
                    // 当所以点都在一条直线上,或者只有一点不在直线上,则直接返回num;
                    System.out.println(num);
                    return;
                }
                // System.out.println(i + "到" + j + "有:" + rp);
                int tmp = rp;
                // 找出直线外一点,以及过这一点与i,j垂直的直线上点的个数;
                for (int m = j + 1; m < num; m++) {
                    if ((x[m] - x[i]) * (y[m] - y[j]) == (x[m] - x[j]) * (y[m] - y[i])) {
                        // m点和i,j在同一条直线上
                        continue;
                    } else {
                        for (int n = 0; n < num; n++) {
                            if (n == m || n == i || n == j) {
                                continue;
                            }
                            if ((x[n] - x[i]) * (y[n] - y[j]) == (x[n] - x[j]) * (y[n] - y[i])) {
                                // n点和i,j在同一条直线上
                                continue;
                            }
                            if ((y[j] - y[i]) * (y[m] - y[n]) + ((x[j] - x[i]) * (x[m] - x[n])) == 0) {
                                tmp++;
                            }
                        }
                        tmp++;// 加上m点;
                        // 此时判断i与j连线外一点m,有多少点与m相连的直线与ij垂直
                        // System.out.println(i+"==>"+j+"==>"+m+"系统有:"+tmp);
                        if (tmp > max) {
                            max = tmp;
                            System.out.print(tmp + "==");
                        }
                        tmp = rp;
                    }
                }
            }
        }
        System.out.println("res:" + max);
    }
}


发表于 2017-12-18 12:58:07 回复(0)