Gym 100015A

原题:
A Another Rock-Paper-Scissors Problem

Sonny uses a very peculiar pattern when it comes to playing rock-paper-scissors. He likes to vary his moves so that his opponent can’t beat him with his own strategy.

Sonny will play rock (R) on his first game, followed by paper (P) and scissors (S) for his second and third games, respectively. But what if someone else is using the same strategy? To thwart those opponents, he’ll then play paper to beat rock, scissors to beat paper, and rock to beat scissors, in that order, for his 4th through 6th games. After that, he’ll play scissors, rock, and paper for games 7–9 to beat anyone copying his last set of moves. Now we’re back to the original order—rock, paper, scissors—but instead of being predictable and using the same moves, do you know what would be better? You guessed it! Sonny then plays the sequence of moves that would beat anyone trying to copy his whole strategy from his first move, and on it goes…

To recap, in symbolic form, Sonny’s rock-paper-scissors moves look like this:

R P S PSR SRP PSRSRPRPS SRPRPSPSR PSRSRPRPSSRPRPSPSRRPSPSRSRP …

The spaces are present only to help show Sonny’s playing pattern and do not alter what move he’ll play on a certain game.

Naturally, your job is to beat Sonny at his own game! If you know the number of the game that you’ll be playing against Sonny, can you figure out what move you would need to play in order to beat him?

A.1 Input

Each line of the input contains a single integer N, 1 ≤ N ≤ 1012, the number of the game you’ll be playing against Sonny. An integer N = 1 indicates it would be Sonny’s first game, N = 7 indicates it would be the 7th game, and so forth. The input terminates with a line with N = 0. For example:

1

7

33

0

Warning: N may be large enough to overflow a 32-bit integer, so be sure to use a larger data type (i.e. long in Java or long long in C/C++) in your program.

A.2 Output

For each test case, output a single line which contains the letter corresponding to the move you would need to play to beat Sonny on that game. For example, the correct output for the sample input above would be:

P

R

S

题目大意:
小明的猜拳策略,先出R,然后每连续两段出拳策略是前一阶段的获胜方法。
样例:
R P S PSR SRP PSRSRPRPS SRPRPSPSR PSRSRPRPSSRPRPSPSRRPSPSRSRP….
第二个P可以赢第一个R,第三个S可以赢第二个P。接着的PSR可以赢前一阶段的RPS,SRP可以赢PSR。然后PSRSRPRPS可以赢R P S PSR SRP,SRPRPSPSR可以赢PSRSRPRPS。以此类推。
求给定轮数胜利的策略。

分析:
通过观察可以发现,这个出拳策略和3有关(显然)。我们可以由3的次方数来分组,递归查找,出拳顺序的变换一定是S->P->R(每一次都要赢前一次的对应位置)。所以如果n是某个3的次方数的(1,2】倍之间,就需要往前推一个拳,如果是(2,3】之间,就需要往前推两个,然后去求n mod这个3的次方数的轮数即可。

ac代码:

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int solve(int cnt);
ll ow(int n,int m);
char res[][4]={"PSR","SRP","RPS"};
ll num;
int main()
{

    while(~scanf("%I64d",&num)&&num)
    {

        int ans;
        ans=solve(0);
        ans=ans%3;
        printf("%c\n",res[num-1][ans]);
    }
}
int solve(int cnt)
{
    if(num>=1&&num<=3)
    return cnt;
    int i=1;
    for(i=1;;i++)
    {
        if(ow(3,i)>=num)
        break;
    }
    if(num>ow(3,i-1)&&num<=2*ow(3,i-1))
    {
        num-=ow(3,i-1);
        solve(cnt+1);
    }
    else if(num>2*ow(3,i-1)&&num<=3*ow(3,i-1))
    {
        num-=2*ow(3,i-1);
        solve(cnt+2);
    }

}
ll ow(int n,int m)
{
    ll res=1;
    for(int i=1;i<=m;i++)
    res=res*n;
    return res;
}

简化版(转):

#include<stdio.h>
long long n,t[26]={1};
char s[4]="RPS";
int main(){
    for(int i=1;i<=25;i++)
        t[i]=t[i-1]*3;
    while(scanf("%I64d",&n)&&n){
        int i=25,a=0;
        while(n>3){
            while(n<=t[i])i--;
            while(n>t[i]){
                n-=t[i];
                a++;//推的次数
            }
        }
        printf("%c\n",s[(n+a)%3]);
        //n为1 2 3,对应PSR
        //a为推的次数
        //(n+a)mod 3为对应的拳
        // 0对应R,1对应P,2对应S
    }
    return 0;
}

博客第一题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值