zoukankan      html  css  js  c++  java
  • ACM: 限时训练题解-Rock-Paper-Scissors-前缀和

    1. Rock-Paper-Scissors

     

    Rock-Paper-Scissors is a two-player game, where each player chooses one of Rock, Paper, or Scissors. Here are the three cases in which a player gets one  point:

    ­          Choosing Rock wins over a player choosing  scissors.

    ­          Choosing Scissors wins over a player choosing  Paper.

    ­          Choosing Paper wins over a player choosing  Rock.

    In all other cases, the player doesn’t get any  points.

    Bahosain and his friend Bayashout played N rounds of this game. Unlike Bayashout, Bahosain was too lazy to decide what to play next for each round, so before starting to play, he chose three integers X Y Z such that X+Y+Z = N and X, Y, Z ≥ 0, and then played Rock for the first X rounds, Paper for the next Y rounds, and Scissors for the last rounds.

    Bayashout got more points in the N rounds and won. Given the moves played by Bayashout in each round, Bahosain wants to know the number of ways in which he could have chosen X, Y and Z such that he wins in the N rounds.

    The winner of the N rounds is the player that gets more total points in the    N rounds.

    Input

     

    The first line of input contains T (1 ≤ T ≤   64), where T is the number of test cases.

    The first line of each test case contains an integer N (1 ≤ N ≤   1000) that represents the number of rounds.

    The next line contains a string of N uppercase letters, the first letter represents the choice of Bayashout for the first round, the second letter represents his choice for the second round, and so on.

    Each letter in the string is one of the following: R (Rock), P (Paper), or S   (Scissors).

    Output

     

    For each test case, print a single line with the number of ways in which Bahosain could have won.

    Sample Input

    Sample Output

    4

    3

    3

    1

    RPS

    1

    1

    5

    R

    5

    PPRSR

    5

    RPSPR

    /*
    题意;A B猜拳,猜N次
    但是A很懒,不想去想怎么猜拳就随机的连续出x次石头 y次布 z次剪刀 
    现在给出B的猜拳的出拳的顺序, 
    然后A以石头R 布P 剪刀S 的顺序出,在出了布之后就不在出石头,出了剪刀后就不再出石头和布 
    问A有多少种可能赢B。 
    
    
    这题一开始不怎么会做,做到限时赛最后还有30分钟的时候又回过头来看这个题目
    不就是一个简单的前缀和么,一开始都没想到。
    
    AC代码: 
    */
    #include"iostream"
    #include"algorithm"
    #include"cstdio"
    #include"cstring"
    #include"cmath"
    #define MX 1000 + 50
    using namespace std;
    int r[MX],p[MX],s[MX],len;
    char str[MX];
    
    int main() {
    	int T;
    	scanf("%d",&T);
    	while(T--) {
    		memset(r,0,sizeof(r));
    		memset(p,0,sizeof(p));
    		memset(s,0,sizeof(s));
    		memset(str,0,sizeof(str));
    		scanf("%d%s",&len,str+1);
    		for(int i=1; i<=len; i++) {
    			if(str[i]=='R') {    //这里用数组rps记录全部出石头布剪刀的得分 【dp-前缀和】 
    				p[i]=p[i-1]+1;		//如果B出的石头 则A的布得分 +1 
    				r[i]=r[i-1];		//A的石头平局,不变 
    				s[i]=s[i-1]-1;		//A的剪刀输扣分 -1 
    			}						//下面一样 
    			if(str[i]=='S') {
    				r[i]=r[i-1]+1;
    				s[i]=s[i-1];
    				p[i]=p[i-1]-1;
    			}
    			if(str[i]=='P') {
    				s[i]=s[i-1]+1;
    				p[i]=p[i-1];
    				r[i]=r[i-1]-1;
    			}
    		}
    		int ans=0;
    		for(int i=0; i<=len; i++) {		//i-1 为连续出石头的次数 r[i]-r[0]为A出石头的得分 
    			for(int j=i; j<=len; j++) { //j-i为连续出布的次数 p[j]-p[i]为A出布的得分 
    				if(r[i]-r[0]+p[j]-p[i]+s[len]-s[j]>0) {   //len-j 为连续出布的次数 s[len]-p[j]为A出剪刀的得分 
    					ans++;		//计算和 如果比0大就算赢。 
    				}
    			}
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    VS2013使用scanf、gets及字符串函数编译报错error C4996: 'scanf': This function or variable may be unsafe. 原因及解决方案
    关于vs2013与office系列软件一起安装出现bug的情况描述以及解决办法——打开vs2013鼠标不动/动不了
    武汉华师驾校学车笔记_纪实
    vs2013由修改模式改为输入模式。
    解析:求最大公约数的“辗转相除法原理”
    关于scanf与scanf_s的区别,以及用scanf编译出错并且提示找不到可执行文件.exe的解决办法。
    [C编译器]在VS中编译调试C程序
    使用vs编译程序选择新建”空项目“与”win32控制台应用程序“的区别。
    AngularJS+Ionic开发-1.搭建开发环境
    PetaPoco源代码学习--3.Sql类
  • 原文地址:https://www.cnblogs.com/HDMaxfun/p/5709336.html
Copyright © 2011-2022 走看看