OJ Rock-Paper-Scissors Tournament

文章描述了一个编程问题,要求编写程序处理石头剪刀布锦标赛的结果,计算每个玩家的平均胜率。输入包括多组测试数据,每组包含玩家数量n和游戏次数k,以及玩家间比赛的具体动作。程序需统计每个玩家的胜败次数并计算胜率,输出结果保留三位小数。示例代码中存在一个问题,即未初始化wins和loses列表,导致无法直接通过索引计数。修正后的代码进行了初始化,以确保可以正确计数并计算胜率。
摘要由CSDN通过智能技术生成

1.题目描述

                                         Rock-Paper-Scissors Tournament     

Problem Description

        Rock-Paper-Scissors is game for two players, A and B, who each choose, independently of the other, one of rock, paper, or scissors. A player chosing paper wins over a player chosing rock; a player chosing scissors wins over a player chosing paper; a player chosing rock wins over a player chosing scissors. A player chosing the same thing as the other player neither wins nor loses. 
        A tournament has been organized in which each of n players plays k rock-scissors-paper games with each of the other players - k*n*(n-1)/2 games in total. Your job is to compute the win average for each player, defined as w / (w + l) where w is the number of games won, and l is the number of games lost, by the player.                          

Input                           

        Input consists of several test cases. The first line of input for each case contains 1 ≤ n ≤ 100 1 ≤ k ≤ 100 as defined above. For each game, a line follows containing p1, m1, p2, m2. 1 ≤ p1 ≤ n and 1 ≤ p2 ≤ n are distinct integers identifying two players; m1 and m2 are their respective moves ("rock", "scissors", or "paper"). A line containing 0 follows the last test case. 

Output

        Output one line each for player 1, player 2, and so on, through player n, giving the player's win average rounded to three decimal places. If the win average is undefined, output "-". Output an empty line between cases.

Sample Input

2 4
1 rock 2 paper
1 scissors 2 paper
1 rock 2 rock
2 rock 1 scissors
2 1
1 rock 2 paper
0

Sample Output

0.333
0.667

0.000
1.000

2.中文翻译

                                                        石头剪刀锦标赛

题目描述:

        石头剪刀布是由A和B两名玩家玩的游戏,他们各自独立地选择石头、纸或剪刀中的一种。选择纸张的玩家胜过选择石头的玩家;选择剪刀的选手胜过选择纸张的选手;选择石头的玩家胜过选择剪刀的玩家。一个玩家选择与另一个玩家相同的东西,既不赢也不输。

        已经组织了一场比赛,n名选手中的每一位与其他选手中的每个选手玩k个石头剪刀布游戏——总共 k*n*(n-1)/2 场游戏。你的工作是计算每个玩家的平均获胜次数,定义为 w/(w+l),其中w是玩家赢得的游戏次数,l是玩家输掉的游戏次数。

输入

        输入由几个测试用例组成。每种情况的第一行输入包含1≤n≤100 ,1≤k≤100,如上所述:(n代表参赛人数,k代表每个人要比赛的游戏数)。对于每个游戏,后面紧跟包含p1、m1、p2、m2的一行。其中,1≤p1≤n和1≤p2≤n是识别两个参与者的不同整数;m1和m2是它们各自的动作(“石头”、“剪刀”或“布”)。最后一个测试用例一行包含0。

输出

        为玩家1、玩家2、直到玩家n输出一行胜率,将玩家的获胜平均值四舍五入到小数点后三位。如果未定义获胜平均值,则输出“-”。在不同情况之间输出一个空行。

样例输入

2 4
1 rock 2 paper
1 scissors 2 paper
1 rock 2 rock
2 rock 1 scissors
2 1
1 rock 2 paper
0

样例输出

0.333
0.667

0.000
1.000

3.思路解析

这道题没什么难度(认真读懂题目就行了),就是注意细节:规则就是剪刀石头布,然后表示的时候可以用str来取第一个字母代表一种手法比如r代表rock;然后用数组计数 (同样的也可以采用字典的方法计数);

4.代码实现

我认为逻辑正确但是语法有点问题(已解决)的代码,正确代码在下面的改进代码

#encoding=utf-8
import math
while(True):
    inputstr=input()
    if inputstr=='0':
        break
    else:
        n,k=map(int,inputstr.split())
        m=int(k*n*(n-1)/2)

        #下面两个数组用来保存不同玩家输赢的次数 比如wins[1]=5 就代表1号玩家赢了5次
        wins=list()
        loses=list()

        for i in range(m):
            p1,m1,p2,m2=input().split()
            p1=int(p1)
            p2=int(p2)
            m1=str(m1)
            m2=str(m2)
            if m1[0]=="r" and m2[0]=="s" or m1[0]=="s" and m2[0]=="p" or m1[0]=="p" and m2[0]=="r":
                wins[p1]+=1
                loses[p2]+=1
            elif m2[0]=="r" and m1[0]=="s" or m2[0]=="s" and m1[0]=="p" or m2[0]=="p" and m1[0]=="r":
                wins[p2]+=1
                loses[p1]+=1
            else:
                pass
        for i in range(1,n+1):
            if (wins[i]==0 and loses[i]==0):
                print("-")
            else:
                print("{:.3f}".format(wins[i]/(wins[i]+loses[i])))

错误提示信息:

 自己做的测试:

gpt给的解决方案:

 意思就是我虽然创建了两个list,但是此时两个list中并没有元素,虽然在python中list是可变长的,但是还是要先进行0初始化的工作才能利用下标直接进行计数:

改进代码

#encoding=utf-8
import math
while(True):
    inputstr=input()
    if inputstr=='0':
        break
    else:
        #n,k表示比赛的人数和每个人比赛的场数
        n,k=map(int,inputstr.split())
        
        #m表示一共游戏的次数
        m=int(k*n*(n-1)/2)

        #下面两个数组用来保存不同玩家输赢的次数 比如wins[1]=5 就代表1号玩家赢了5次
        wins=[0]*10086
        loses=[0]*10086
        
        #主程序
        for i in range(m):
            p1,m1,p2,m2=input().split()
            p1=int(p1)
            p2=int(p2)
            m1=str(m1)
            m2=str(m2)
            if m1[0]=="r" and m2[0]=="s" or m1[0]=="s" and m2[0]=="p" or m1[0]=="p" and m2[0]=="r":
                wins[p1]+=1
                loses[p2]+=1
            elif m2[0]=="r" and m1[0]=="s" or m2[0]=="s" and m1[0]=="p" or m2[0]=="p" and m1[0]=="r":
                wins[p2]+=1
                loses[p1]+=1
            else:
                pass
        for i in range(1,n+1):
            if (wins[i]==0 and loses[i]==0):
                print("-")
            else:
                print("{:.3f}".format(wins[i]/(wins[i]+loses[i])))
        #换行
        print()

 

杭州电子科技大学在线评测系统(杭电OJ)中的题目1000-1100是一系列编程题,我将分别进行回答。 1000题是一个简单的入门题,要求计算两个整数的和。我们可以使用一个简单的算法,读取输入的两个整数,然后将它们相加,最后输出结果即可。 1001题是一个稍微复杂一些的题目,要求实现字符串的逆序输出。我们可以使用一个循环来逐个读取输入的字符,然后将这些字符存储在一个数组中。最后,我们可以倒序遍历数组并将字符依次输出,实现字符串的逆序输出。 1002题是一个求最大公约数的问题。我们可以使用辗转相除法来解决,即先求出两个数的余数,然后将被除数更新为除数,将除数更新为余数,直至两个数的余数为0。最后的被除数就是最大公约数。 1003题是一个比较简单的排序问题。我们可以使用冒泡排序算法来解决,即每次比较相邻的两个元素,如果它们的顺序错误就交换它们的位置。重复这个过程直至整个数组有序。 1100题是一个动态规划问题,要求计算给定序列中的最长上升子序列的长度。我们可以使用一个数组dp来保存到达每个位置的最长上升子序列的长度。每当遍历到一个位置时,我们可以将其和之前的位置比较,如果比之前位置的值大,则将其更新为之前位置的值加1,最后返回dp数组的最大值即可。 以上是对杭电OJ1000-1100题目的简要回答,涉及了一些基本的编程知识和算法思想。希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值