AcWing 1801. 蹄子剪刀布 附图 超详细

18 篇文章 0 订阅
17 篇文章 0 订阅

题目

你可能听说过“石头剪刀布”的游戏。

这个游戏在牛当中同样流行,它们称之为“蹄子剪刀布”。

游戏的规则非常简单,两头牛相互对抗,数到三之后各出一个表示蹄子,剪刀或布的手势。

蹄子赢剪刀,剪刀赢布,布赢蹄子。

例如,第一头牛出“蹄子”手势,第二头牛出“布”手势,则第二头牛获胜。

如果两头牛出相同的手势,则算平局。

农夫约翰的两头奶牛正在进行 N 轮“蹄子剪刀布”对抗,他看的十分入迷。

不幸的是,虽然他可以看到奶牛正在做出三种不同类型的手势,但他却无法分辨出哪一个代表“蹄子”,哪一个代表“布”以及哪一个代表“剪刀”。

不知道这三种手势的具体含义的情况下,农夫约翰给这三种手势分配了编号 1,2,3。

手势 1 可能代表“蹄子”,可能代表“剪刀”,也可能代表“布”,反正他傻傻分不清楚。

给出两头奶牛在 N 场比赛中所做出的具体手势对应的编号,请你判断第一头奶牛最多可能赢多少盘对抗。

输入格式
第一行包含整数 N。

接下来 N 行,每行包含两个整数(1 或 2 或 3),表示两头奶牛在一轮对抗中所出的手势对应的编号。

输出格式
输出第一头奶牛可能获胜的最大场次数。

数据范围
1 ≤ N ≤ 100

输入样例:

5
1 2
2 2
1 3
1 1
3 2

输出样例:

2

样例解释
此样例的一种解决方案是,1 表示剪刀,2 表示蹄子,3 表示布。

这样,第一头奶牛可以赢得 (1,3) 和 (3,2) 两场比赛。

解题思路

首先,对于1,2,3 三个数,有以下八种排列方式:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

这八种排列方式分别对应以下八种赢的方式:
1 2 3 -> 1 赢 2,2 赢 3,3 赢 1
1 3 2 -> 1 赢 3,3 赢 2,2 赢 1
2 1 3 -> 2 赢 1,1 赢 3,3 赢 2
2 3 1 -> 2 赢 3,3 赢 1,1 赢 2
3 1 2 -> 3 赢 1,1 赢 2,2 赢 3
3 2 1 -> 3 赢 2,2 赢 1,1 赢 3

当我们将这八种方式画成环后,其实只有如下图的两种方式:
方式1
方式2

对于上面那张图来说:
即 1 赢 2,2 赢 3,3 赢 1;
也就是第一头牛出的值与第二头牛出的值之差为 -1 和 2 时获胜;

对下面那张图来说:
1 赢 3,3 赢 2,2 赢 1;
也就是第一头牛出的值与第二头牛出的值之差为 -2 和 1 时获胜;

而如果二者出的相同,第一头牛出的值与第二头牛出的值之差为0,则平局,无需考虑。

所以我们只要将第一头牛出的值与第二头牛出的值之差为 -2 和 1 之和 与 第一头牛出的值与第二头牛出的值之差为 -2 和 1 之和作比较,较大的就是第一头牛可能赢的最大次数。

AC 代码

Java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class Main1801 {
	
	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(System.out);
		
		int n = Integer.parseInt(in.readLine());
		int[] win = new int[5];
		
		while(n-- > 0) {
			String str = in.readLine();
			// 1 赢 2,2 赢 3, 3 赢 1 时
			// -1 代表 1 赢 2,2 赢 3 的情况,对应下标 1
			// 2 代表 3 赢 1 的情况,对应下标 4
			
			// 1 赢 3,3 赢 2, 2 赢 1 时
			// 1 代表 3 赢 2,2 赢 1 的情况,对应下标 3
			// -2 代表 1 赢 3 的情况,对应下标 0
			win[Integer.parseInt(str.split(" ")[0]) - Integer.parseInt(str.split(" ")[1]) + 2]++;
		}
		
		// 下标 1 和 4 对应 1 赢 3,3 赢 2, 2 赢 1 的情况
		// 下标 0 和 3 对应 1 赢 2,2 赢 3, 3 赢 1 的情况
		out.print(Math.max(win[1] + win[4], win[0] + win[3]));
		out.flush();
		in.close();
	}

}

C++

#include<iostream>

using namespace std;

int n;
int win[5];

int main()
{
    scanf("%d", &n);

    while(n--)
    {
        int a = 0;
        int b = 0;
        scanf("%d%d", &a, &b);

        // 1 赢 2,2 赢 3, 3 赢 1 时
        // -1 代表 1 赢 2,2 赢 3 的情况,对应下标 1
        // 2 代表 3 赢 1 的情况,对应下标 4

        // 1 赢 3,3 赢 2, 2 赢 1 时
        // 1 代表 3 赢 2,2 赢 1 的情况,对应下标 3
        // -2 代表 1 赢 3 的情况,对应下标 0
        win[a - b + 2]++;
    }

    // 下标 1 和 4 对应 1 赢 3,3 赢 2, 2 赢 1 的情况
    // 下标 0 和 3 对应 1 赢 2,2 赢 3, 3 赢 1 的情况
    printf("%d", max(win[0] + win[3], win[1] + win[4]));
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值