WUSTOJ 1336: Lucky Boy(Java)博弈

108 篇文章 0 订阅
80 篇文章 18 订阅

题目链接:1336: Lucky Boy
参考博客:LUCKY BOY 博弈——HandsomeHow

Description

Recently, Lur have a good luck. He is also the cleverest boy in his school as he create the most popular computer game – Lucky Boy. The game is played by two players, a and b, in 2d planar .In the game Lucky Boy, there are n different points on plane, each time one can remove one or multiple co-line points from the plane. The one who can firstly remove more than two points from the plane wins. The one who removes the last point on the plane can also win the game. You may assume that two players are both clever enough that they can always make the best choice. The winner is called Lucky Boy.
Given the n points, can you tell me who will be the Lucky Boy ? Note that player a will always the first one to remove points from the plane.

在一个二维平面,有 n 个不同的点,每次可以从平面上拿走一个点或者在一条直线上的多个点。先拿走两个以上的点或者拿走最后一个点的人获胜。问谁获胜?

Input

The first line of each case is an integer n(0<n<=103), following n lines each contains two integers x and y(0<=x, y<=108), describing the coordinates of each point. Ended by EOF.

Output

Output “a is the lucky boy.” in a single line if a win the game, otherwise you should output “b is the lucky boy.” in a single line.

Sample Input

3
0 0
1 1
2 2
3
0 0
1 1
2 3
4
0 0
1 1
2 2
3 5
4
0 0
0 1
1 1
1 0

Sample Output

a is the lucky boy.
b is the lucky boy.
a is the lucky boy.
a is the lucky boy.

分析?

(⊙o⊙)…博弈的题目我做的还是有点少,看起来不难,我也不会做。。。感觉我阅读有问题?

思路来源于参考博客。

  • 至少3个点在一条直线上,a肯定获胜,因为他先手。
  • 最多2个点在一条直线上,如果a想要获胜,那么最后1个或2个点必须要自己拿,因此他应该给b留3个点,要想给b留3个点,那么前一步a必须要给b留6个点。也就是说只要a拿完后将点的个数保持为3m即可获胜。
    • 所以如果n不是3的倍数,那么a一定获胜。
    • 如果是3的倍数,那么a一定输。

按照上面方法:1、先判断是否有3个点在一条直线上;2、判断是否是3的倍数。

很明显第一步要三层循环,第二步只需要一个if判断。因此应该将第二步作为先行判断条件,从而减小进入循环的可能性。即:

  • n不是3的倍数
    • 至少3个点在一条直线上,a胜
    • 最多2个点在一条直线上,a胜
  • n是3的倍数
    • 至少3个点在一条直线上,a胜
    • 最多2个点在一条直线上,a输

代码?

/**
 * Time 634ms
 * @author wowpH
 * @version 1.0
 * @date 2019年6月29日下午10:05:57
 * Environment:	Windows 10
 * IDE Version:	Eclipse 2019-3
 * JDK Version:	JDK1.8.0_112
 */

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			int n = sc.nextInt();// 点的个数
			int[][] p = new int[n][2];// 保存坐标
			for (int i = 0; i < n; ++i) {
				p[i][0] = sc.nextInt();
				p[i][1] = sc.nextInt();
			}
			boolean aWin = false;// 初始a输
			if (0 != n % 3) {
				aWin = true;// 不是3的倍数,a获胜
			} else {// 是3的倍数
				// 判断是否有3个点在一条直线
				for (int i = 0; i < n && false == aWin; ++i) {
					for (int j = i + 1; j < n && false == aWin; ++j) {
						for (int k = j + 1; k < n && false == aWin; ++k) {
							int a = (p[i][0] - p[j][0]) * (p[i][1] - p[k][1]);
							int b = (p[i][0] - p[k][0]) * (p[i][1] - p[j][1]);
							if (a == b) {
								aWin = true;// 点i,j,k在一条直线,a获胜
							}
						}
					}
				}
			}
			if (true == aWin) {
				System.out.println("a is the lucky boy.");
			} else {
				System.out.println("b is the lucky boy.");
			}
		}
		sc.close();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值