IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Coin Stack——Java版详解 -> 正文阅读

[Java知识库]Coin Stack——Java版详解

题目描述

A and B are playing a collaborative game that involves n stacks of coins, numbered from 1 to n. Every round of the game, they select a nonempty stack each, but they are not allowed to choose the same stack. They then remove a coin from both the two selected stacks and then the next round begins.

The players win the game if they manage to remove all the coins. Is it possible for them to win the game, and if it is, how should they play?

输入描述:

 

The first line of input contains an integer n (2 ≤ n ≤ 50), the number of coin stacks. Then follows a line containing n nonnegative integers a1, a2, . . . , an, where ai is the number of coins in the i’th stack. The total number of coins is at most 1000.

输出描述:

 

If the players can win the game, output a line containing “yes”, followed by a description of the moves. Otherwise output a line containing “no”. When describing the moves, output one move per line, each move being described by two distinct integers a and b (between 1 and n) indicating that the players remove a coin from stacks a and b. If there are several possible solutions, output any one of them.

示例1

输入

3

1 4 3

输出

yes
1 2
2 3
2 3
2 3

示例2

输入

3
1 1 1

输出

no

原题链接:https://ac.nowcoder.com/acm/contest/18456/C
来源:牛客网

原文翻译

A和B正在玩一个合作游戏,游戏中涉及n个硬币堆,编号从1到n。然后,他们从两个选定的堆栈中取出一枚硬币,然后开始下一轮游戏。

第一行输入包含一个整数n(2≤n≤50),即硬币堆的数量。然后是一行包含n个非负整数a1, a2, ... ?, an,其中ai是第i个硬币堆中的硬币数量。硬币的总数最多为1000。

如果玩家能够赢得比赛,则输出包含 "是 "的一行,后面是对棋步的描述。否则就输出包含 "否 "的一行。在描述动作时,每行输出一个动作,每个动作由两个不同的整数a和b(介于1和n之间)描述,表示玩家从堆栈a和b中取出一枚硬币。

心路历程

第一次解题:

第一次尝试解题时想的比较简单,首先既然一次拿俩个,拿硬币数一定要先是偶数才成立;然后就是取硬币的过程,起初认为只要用两个指针分别指向两个钱币数不为0的洞上,让其不相遇然后循环取钱币,直至钱币取完。

这种思路通过48%的样例,原因是操作思路太简单,指针的运动是历遍顺序,缺乏机动性:

这里举一个栗子:

1 2 3 4

0 1 3 4

0 0 2 4

0 0 1 3

0 0 0 3

按照原来的思想用俩指针找硬币数不为0的两个洞取出,会出现指针相遇而判no的情况,实际上该样例可以通过。

第二次解题:

经过上一次的教训,我认定两指针的运动一定要满足弄种规律

这时我结合了实际,将自己代入题中;假如我们现在在玩这样一个游戏,想要一次在不同的洞里取出两个硬币,我们肯定不可能一根筋,哪有就找那,那样太没有大局观。

正常的我们一定会有一个预判思想,去保证至少有两个洞中硬币数不为0,避免最后只剩一个洞有硬币,而失败的结局。

这时,我就有了想法,类似一种分苹果的思想,要去保证每个人都感到合理,我们一般都会让苹果多的匀给少的。在本题中,最多和最少就是解题的关键所在。

举个栗子:

对于这个样例:1?1?6?8?9?11

我们为了去保证至少有两个洞中硬币数不为0;每次找一个最大最小值,让其下标不同,这样就保证了这一点;紧接着每次都从最大最小值对应的洞口取出该轮的两枚硬币,直至取完,便可完成过程。下面是该样例的模拟操作步骤:

1 1 6 8 9 11
0 1 6 8 9 10
0 0 6 8 9 9
0 0 5 8 9 8
0 0 4 8 8 8
0 0 3 8 8 7
0 0 2 8 7 7
0 0 1 7 7 7
0 0 0 7 7 6
0 0 0 7 6 6
0 0 0 6 6 6?
0 0 0 5 6 5
0 0 0 4 5 5
0 0 0 3 5 4
0 0 0 2 4 4
0 0 0 1 4 3
0 0 0 0 3 3
0 0 0 0 2 2
0 0 0 0 1 1
0 0 0 0 0 0

(这里要提示的一点是:当min=max时,要保证其对应的下标是不同的才能继续)

代码块:


import java.io.*;

public class Main {
    static StreamTokenizer r;
    static PrintWriter pr;
    static BufferedReader re;
    static boolean isFlag = true;

    static {
        r = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        pr = new PrintWriter(new OutputStreamWriter(System.out));
        re = new BufferedReader(new InputStreamReader(System.in));
    }


    static int maxcursor;
    static int mincursor;
    static int Thecount;
    static int index = 0;

    static int cc[];/*记录数据*/
    static int nec[];/*记录答案*/

    public static void main(String[] args) throws IOException {
        int a = ini();
        cc = new int[a];

        for (int i = 0; i < cc.length; i++) {
            cc[i] = ini();
            Thecount += cc[i];
        }
        nec = new int[Thecount];

        if (Thecount % 2 == 0) {
            while (Thecount != 0) {
                 maxMin(cc);
                if (maxcursor == mincursor) {
                    isFlag = false;
                    break;
                }
               
                
            }
            if (isFlag) {
                System.out.println("yes");
                for (int i = 0; i < nec.length; i += 2) {
                    System.out.println((nec[i] + 1) + " " + (nec[i + 1] + 1));
                }
            } else {
                System.out.println("no");
            }

        } else {
            System.out.println("no");
        }


    }

    static int ini() throws IOException {
        r.nextToken();
        return (int) r.nval;
    }

    static void maxMin(int a[]) {//对于每个回合,我们都要找到数组的最大最小值
        int b[] = a;
        int max = -1;
        int min = 1001;//注意点
        int index1 = -2;
        int index2 = -1;
        for (int i = 0; i < b.length; i++) {
            if (b[i] == 0) {
                continue;
            } else {
                if (b[i] < min) {
                    min = b[i];
                    index1 = i;
                }
                if (b[i] >= max) {
                    max = b[i];
                    index2 = i;
                }
            }
        }
        mincursor = index1;
        maxcursor = index2;

        nec[index] = mincursor;
        cc[mincursor]--;
        index++;

        nec[index] = maxcursor;
        cc[maxcursor]--;
        index++;

        Thecount -= 2;
    }

}

留在最后

这个题我想吐槽一点的时,“The total number of coins is at most 1000.”以及“The first line of input contains an integer n (2 ≤ n ≤ 50)”这两段话让我深感无语。

按理说n>=2,那么对于任意洞口,它的硬币数不会超过999;但当我们把min设为1000时,在部分案例会出现:数组越界的情况。

?分析了下,可能情况就是某个样例的硬币数没有小于1000的,导致在找最小值下标时未得到结果,mincursor直接等于了初始值-2;导致超出了数组cc的下标范围。

?

当我们把min的初始值改为1001时,问题得到了解决。


?

?

?

?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-05 17:11:57  更:2021-08-05 17:14:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/12 5:32:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码