计蒜客 Rock Paper Scissors Lizard Spock.

传送门

Didi is a curious baby. One day, she finds a curious game, which named Rock Paper Scissors Lizard Spock.

The game is an upgraded version of the game named Rock, Paper, Scissors. Each player chooses an option . And then those players show their choices that was previously hidden at the same time. If the winner defeats the others, she gets a point.

The rules are as follows. 

Scissors cuts Paper

Paper covers Rock

Rock crushes Lizard

Lizard poisons Spock

Spock smashes Scissors

Scissors decapitates Lizard

Lizard eats Paper

Paper disproves Spock

Spock vaporizes Rock

(and as it always has) Rock crushes Scissors.

(this pic is from baike.baidu.com)

But Didi is a little silly, she always loses the game. In order to keep her calm, her friend Tangtang writes down the order on a list and show it to her. Didi also writes down her order on another list, like p1.png.

(Rock-R Paper-P Scissors-S Lizard-L Spock-K)

However, Didi may skip some her friends' choices to find the position to get the most winning points of the game, like p2.png

Can you help Didi find the max points she can get?

Input:

The first line contains the list of choices of Didi's friend, the second line contains the list of choices of Didi.

(1<=len(s2)<=len(s1)<=1e6)

Output:

One line contains an integer indicating the maximum number of wining point.

忽略每行输出的末尾多余空格

样例输入1

RRRRRRRRRLLL
RRRS

样例输出1

3

样例输入2

RSSPKKLLRKPS
RSRS

样例输出2

2

【题意】

加强版的石头剪刀布,两个人玩五种手势的类似石头剪刀布的游戏。给出两个人的出的顺序,你是第二个人,你可以选择从某个回合开始出,问你最多能赢几局游戏。

【分析】

已经有题解了,就是fft。就让本蒟蒻来阐述一下解题过程。

首先,如果游戏简化一下,简化成石头剪刀布的三种手势的游戏,可能比较容易想到。那么二者之间有什么联系呢?

比较容易想到的是:五种手势相互独立,意思就是我们可以把这一个游戏拆成五个游戏来考虑。

就是说,我们枚举一个手势,将第二个人的这个手势出现的位置标记出来,将第一个人对应这个手势的败状态标记出来。如果两个标记相遇了,那么比较容易想到的是对应的这个局面第二个人胜利。

所以我们的做法是,枚举每一个手势,假设是“S”,那么我们就将第二个人所有的“S”标记成1,其他的标记成0,对应的第一个人的“P”或者“L”标记成1,其他的标记成0,这样可以得到两个0,1串。我们将这两个01串乘起来,就可以得到对应的能胜利的最大局数,注意这个是S对应的胜利局数。然后我们将枚举得到的五个手势统计一下和。然后取一个max就是答案。

【代码】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<sstream>
using namespace std;
///---------------------------------------------------------------------------------
const double PI = acos(-1.0);
const int maxm = 2e6+10;
class comp
{
public:
    double real,imag;
    comp(double _real=0.0,double _imag=0.0)
    {
        real=_real;
        imag=_imag;
    }
    comp operator - (const comp &b) const
    {
        return comp(real-b.real,imag-b.imag);
    }
    comp operator + (const comp &b) const
    {
        return comp(real+b.real,imag+b.imag);
    }
    comp operator * (const comp &b) const
    {
        return comp(real*b.real-imag*b.imag,real*b.imag+imag*b.real);
    }
    void setValue(double _real = 0.0,double _imag = 0.0)
    {
        real=_real;
        imag=_imag;
    }
};
comp A[maxm],B[maxm];
int res[maxm],len,mlen,len1,len2;
char str1[maxm>>1],str2[maxm>>1];

void swap(comp &a,comp &b)
{
    comp c=a;
    a=b;
    b=c;
}
void prepare()
{
    mlen=max(len1,len2);
    len=1;
    while(len<(mlen<<1))
        len<<=1;
    for(int i=0;i<len1;i++)
        A[i].setValue(str1[len1-i-1]-'0',0);

    for(int i=0;i<len2;i++)
        B[i].setValue(str2[len2-i-1]-'0',0);

    for(int i=len1;i<len;i++)
        A[i].setValue();

    for(int i=len2;i<len;i++)
        B[i].setValue();
}
void rader(comp y[])
{
    for(int i=1,j=len>>1,k;i<len-1;i++)
    {
        if(i<j) swap(y[i],y[j]);
        k=len>>1;
        while(j>=k)
        {
            j-=k;
            k>>=1;
        }
        if(j<k)
            j+=k;
    }
}
void FFT(comp y[],int op)
{
    rader(y);
    for(int h=2;h<=len;h<<=1)
    {
        comp wn(cos(op*2*PI/h),sin(op*2*PI/h));
        for(int i=0;i<len;i+=h)
        {
            comp w(1,0);
            for(int j=i;j<i+h/2;j++)
            {
                comp u=y[j];
                comp t=w*y[j+h/2];

                y[j]=u+t;
                y[j+h/2]=u-t;
                w=w*wn;
            }
        }
    }
    if(op==-1)
        for(int i=0;i<len;i++)
            y[i].real/=len;
}
void convolution(comp *a,comp *b)
{
    FFT(a,1);
    FFT(b,1);
    for(int i=0;i<len;++i)
        a[i]=a[i]*b[i];
    FFT(a,-1);
    for(int i=0;i<len;i++)
        res[i]=(int)(a[i].real+0.5);
}
int ans[maxm];
char stra[maxm],strb[maxm];

void add(){
    for(int i = 0;i<len;i++){
        ans[i]+=res[i];
    }
}
void pri(){
    int now = 0;
    for(int i = 0;i<len;i++){
        now = max(now,ans[i]);
    }
    printf("%d\n",now);
}
char que[10]="SPRLK";
char son[10][2];
int main()
{
//    freopen("in.txt","r",stdin);
    son[0][0] = 'P'; son[0][1] = 'L';
    son[1][0] = 'R',son[1][1] = 'K';
    son[2][0] = 'S',son[2][1] = 'L';
    son[3][0] = 'P',son[3][1] = 'K';
    son[4][0] = 'S',son[4][1] = 'R';

    scanf("%s %s",stra,strb);
    len1 = strlen(stra);
    len2 = strlen(strb);
    reverse(strb,strb+len2);
    str1[len1] = '\0';str2[len2] = '\0';
    for(int win = 0;win<5;win++){
        for(int i = 0;i<len2;i++)
            str2[i] = que[win]==strb[i]?'1':'0';
        for(int i = 0;i<len1;i++)
            str1[i] = son[win][0]==stra[i]||son[win][1]==stra[i]?'1':'0';
        prepare();
        convolution(A,B);
        add();
    }
    pri();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/mengzhongsharen/article/details/80067675