JavaScript PAT乙级题解 1018锤子剪刀布

题目如下:

大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:

现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。

输入格式:

输入第 1 行给出正整数 N(≤105),即双方交锋的次数。随后 N 行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C 代表“锤子”、J 代表“剪刀”、B 代表“布”,第 1 个字母代表甲方,第 2 个代表乙方,中间有 1 个空格。

输出格式:

输出第 1、2 行分别给出甲、乙的胜、平、负次数,数字间以 1 个空格分隔。第 3 行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有 1 个空格。如果解不唯一,则输出按字母序最小的解。

输入样例:

10
C J
J B
C B
B B
B C
C C
C B
J B
B C
J J

输出样例:

5 3 2
2 3 5
B B

题解如下:

wq这下真的感觉到自己有了那么一丢丢进步了,写的代码居然一遍过了!!!!!!喜大普奔啊感动到落泪呜呜呜呜呜呜,不枉费我写了这么久呜呜呜呜

ok fine言归正传

这个题说不麻烦又有点麻烦,说麻烦吧他的逻辑又很简单,总想着这么写太low了不行我要把它写得更简洁一点,用一个更好的逻辑处理,然后就一直纠结,这样写好傻,但是又想不出来更好的办法,纠结了一会,哎拉倒吧只能这样了能写出来都不错了。

这写的也太low了,我自己都不好意思往外发,怕别人看了笑话我,是怎么能写出来这么傻的东西的啊哈哈哈哈哈哈,还好没什么人看,我就自娱自乐了

这里有一个逻辑就是甲胜乙必负,甲平乙必平

我用了两个数组分别存储甲赢的时候出的手势和乙赢的时候出的手势,通过Win方法对这组数据进行循环统计,统计完之后通过获取两个数组的长度和输入数据的长度就可以得到他们的胜、负、平次数。

再对这两个数组分别统计他们赢得最多的手势,用了一个数组jcb来存储赢的时候出J、C、B的次数,再找最大值;这里有一个要注意的点就是如果有次数相同的情况取字母序最小的那个,所以jcb数组存储的数据就很关键了,先字母序大的再字母序小的,这样后面的如果跟前面的相等的话就可以用>=把前面的覆盖掉,就不用再处理了。

var readline = require('readline');
var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

var num = 0;
var rows = []; //存储每行的输入
rl.on('line',function(data) {
    if(num == 0) {
        num = parseInt(data.trim()); //读取第一行
    } else {
        rows.push(data.trim());
        if(num == rows.length) {
            deal(rows);
        }
    }
})

var jiaArr = []; //甲赢的时候出的手势
var yiArr = []; //乙赢的时候出的手势
function deal(input) {
    for(var i = 0; i < input.length; i++) {
        var arr = input[i].split(' ');
        Win(arr[0], arr[1]);
    }
    var win = jiaArr.length;
    var ping = input.length-jiaArr.length-yiArr.length;
    var lose = yiArr.length;
    console.log(win+' '+ping+' '+lose);
    console.log(lose+' '+ping+' '+win);
    var jiaWin = winMost(jiaArr);
    var yiWin = winMost(yiArr);
    console.log(jiaWin + ' ' + yiWin);
}

// 石头剪刀布的规则 C>J J>B B>C 甲胜存jiaArr,乙胜存yiArr
// 数组长度就是他们赢的次数,也便于后续计算他们赢最多的手势
function Win(a, b) {
    if(a == b) return;
    if(a == 'C') {
        if(b == 'J') jiaArr.push(a);
        else yiArr.push(b);
    } else if(a == 'J') {
        if(b == 'B') jiaArr.push(a);
        else yiArr.push(b);
    } else {
        if(b == 'C') jiaArr.push(a);
        else yiArr.push(b);
    }
}

// 计算获胜次数最多的手势
function winMost(arr) {
    var jcb = [0,0,0];
    for(var i = 0; i < arr.length; i++) {
        if(arr[i] == 'J') jcb[0]++;
        else if(arr[i] == 'C') jcb[1]++;
        else jcb[2]++;
    }
    var max = jcb[0];
    var maxNum = 0
    // 不用再考虑解不唯一要输出字母序最小的解了,因为在排序的时候就是按字母序排的,
    // 字母序最大的J在最前面,最小的B在最后面,就算他们相等,后面的B也一定会覆盖掉前面的
    for(var i = 1; i < jcb.length; i++) {
        // 这里写的>=,便于相等的情况后面的覆盖掉前面的
        if(jcb[i] >= max) {
            max = jcb[i];
            maxNum = i;
        }
    }
    if(maxNum == 0) return 'J';
    else if(maxNum == 1) return 'C';
    else return 'B';
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值