• FFT(Rock Paper Scissors Gym


    题目链接:https://vjudge.net/problem/Gym-101667H

    题目大意:首先给你两个字符串,R代表石头,P代表布,S代表剪刀,第一个字符串代表第一个人每一次出的类型,第二个字符串代表第二个人每一次出的类型,问怎么控制第二个人开始的地方,能使得第二个人获胜的几率最大,然后输出最多获胜的局数。

    具体思路:FFT,我们首先把第二个字符串每一个类型全部转换成他的对立面,比如说石头就转换成布,布就转换成剪刀,剪刀就转换成石头,然后我们就直接用第二个字符串去匹配就可以了。

    匹配的时候,我们是将三个分着进行的,先求从每一个位置开始子串的最大匹配量,三个分别求好之后,我们就遍历一下每一个位置看一下那个位置的最大匹配量就可以了。

    AC代码:

      1 #include<iostream>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<stdio.h>
      7 using namespace std;
      8 # define ll long long
      9 const double PI = acos(-1.0);
     10 const int maxn = 4e5+100;
     11 struct complex
     12 {
     13     double r,i;
     14     complex(double _r = 0,double _i = 0)
     15     {
     16         r = _r;
     17         i = _i;
     18     }
     19     complex operator +(const complex &b)
     20     {
     21         return complex(r+b.r,i+b.i);
     22     }
     23     complex operator -(const complex &b)
     24     {
     25         return complex(r-b.r,i-b.i);
     26     }
     27     complex operator *(const complex &b)
     28     {
     29         return complex(r*b.r-i*b.i,r*b.i+i*b.r);
     30     }
     31 };
     32 void change(complex y[],int len)
     33 {
     34     int i,j,k;
     35     for(i = 1, j = len/2; i < len-1; i++)
     36     {
     37         if(i < j)
     38             swap(y[i],y[j]);
     39         k = len/2;
     40         while( j >= k)
     41         {
     42             j -= k;
     43             k /= 2;
     44         }
     45         if(j < k)
     46             j += k;
     47     }
     48 }
     49 void fft(complex y[],int len,int on)
     50 {
     51     change(y,len);
     52     for(int h = 2; h <= len; h <<= 1)
     53     {
     54         complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
     55         for(int j = 0; j < len; j += h)
     56         {
     57             complex w(1,0);
     58             for(int k = j; k < j+h/2; k++)
     59             {
     60                 complex u = y[k];
     61                 complex t = w*y[k+h/2];
     62                 y[k] = u+t;
     63                 y[k+h/2] = u-t;
     64                 w = w*wn;
     65             }
     66         }
     67     }
     68     if(on == -1)
     69         for(int i = 0; i < len; i++)
     70             y[i].r /= len;
     71 }
     72 complex x1[maxn],x2[maxn];
     73 char str1[maxn],str2[maxn];
     74 int sum[maxn],len,len1,len2,ans[maxn];
     75 void cal(char tmp)
     76 {
     77     for(int i=0; i<len1; i++)
     78     {
     79         x1[i]=complex(str1[i]==tmp,0);
     80     }
     81     for(int i=len1; i<len; i++)
     82     {
     83         x1[i]=complex(0,0);
     84     }
     85     for(int i=0; i<len2; i++)
     86     {
     87         x2[i]=complex(str2[len2-i-1]==tmp,0);//记得要将第二个字符串进行翻转。
     88     }
     89     for(int i=len2; i<len; i++)
     90     {
     91         x2[i]=complex(0,0);
     92     }
     93     fft(x1,len,1);
     94     fft(x2,len,1);
     95     for(int i=0; i<len; i++)
     96     {
     97         x1[i]=x1[i]*x2[i];
     98     }
     99     fft(x1,len,-1);
    100     for(int i=0; i<len; i++)
    101     {
    102         sum[i]=(int)(x1[i].r+0.5);
    103     }
    104     for(int i=0; i<len; i++)
    105     {
    106         ans[i]+=sum[i];
    107     }
    108 }
    109 int main()
    110 {
    111     int n,m;
    112     scanf("%d %d",&n,&m);
    113     scanf("%s",str1);
    114     scanf("%s",str2);
    115     len=1;
    116     len1=strlen(str1);
    117     len2=strlen(str2);
    118     while(len<len1*2||len<len2*2)
    119         len<<=1;
    120     for(int i=0; i<len1; i++)
    121     {
    122         if(str1[i]=='R')
    123         {
    124             str1[i]='P';
    125         }
    126         else if(str1[i]=='P')
    127         {
    128             str1[i]='S';
    129         }
    130         else if(str1[i]=='S')
    131         {
    132             str1[i]='R';
    133         }
    134     }
    135     cal('P');
    136     cal('S');
    137     cal('R');
    138     int maxx=0;
    139     for(int i=len2-1; i<len1+len2-1; i++)//注意起点是第二个字符串的长度对应的下标,也就是冷len2-1.
    140     {
    141         maxx=max(maxx,ans[i]);
    142     }
    143     printf("%d
    ",maxx);
    144     return 0;
    145 }
  • 相关阅读:
    @SpringBootApplication注解的理解
    git详解
    什么是maven?
    redis发布订阅实战
    报文示例
    Cisco的ACI究竟是什么?它和SDN有关系吗?
    IP数据包分析
    ARP数据包分析
    水冷精密空调工作原理
    风冷精密空调工作原理
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10301962.html
Copyright © 2020-2023  润新知