Problem H Rock Paper Scissors,FFT
生活随笔
收集整理的這篇文章主要介紹了
Problem H Rock Paper Scissors,FFT
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目
題目鏈接
題意
給出兩段石頭剪刀布的順序SS和TT,其中TT要短一些,現在讓你把TT往SS的某個位置上靠,使得靠好了以后,TT能贏SS的子段的次數最大。
如圖:
題解
這道題很典型的FFT啦,首先我們把TT序列換成它能贏的序列T′T′,也就是TT序列中的R、S、PR、S、P對應的換成S、P、RS、P、R形成T′T′。
這樣的話,我們只需要在SS中找一段匹配程度最大的就可以了,這的最大的匹配程度就是答案。
為了匹配,我們把T′T′倒換過來,記為rT′rT′,我們想象一下做卷積的過程,
發現新的卷積序列中的第kk個位置的值等于S[k?lenT,k?1]S[k?lenT,k?1]與T′T′序列對應位置乘積之和。
為了使用卷積解決這個問題,我們把問題拆成3部分,即單獨考慮P、S、RP、S、R時候,最大匹配程度,最后將相同位置的匹配程度加起來就可以了。
代碼
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; double pi = acos(-1.0); struct complex{double re,im;complex(double r = 0.0,double i = 0.0):re(r),im(i){};complex operator+(complex com){return complex(re+com.re,im+com.im);}complex operator-(complex com){return complex(re-com.re,im-com.im);}complex operator*(complex com){return complex(re*com.re-im*com.im,re*com.im+im*com.re);} }; complex wn,wntmp; void rader(complex arr[],int n){int num = n-1;for(int i = 0;i < n;++i){int tn = n>>1;while(num && num >= tn) num ^= tn,tn >>= 1;num |= tn;if(num > i) swap(arr[i],arr[num]);} } void FFT(complex cs[],int n,int f){rader(cs,n);for(int s = 1;s < n;s <<= 1){wn = complex(cos(f*2*pi/(s*2)),sin(f*2*pi/(s*2)));for(int offset = 0;offset < n;offset += s<<1){wntmp = complex(1.0,0.0);for(int i = 0;i < s;++i){complex u = cs[offset+i],v = cs[offset+i+s]*wntmp;cs[offset+i] = u + v;cs[offset+i+s] = u - v;wntmp = wntmp * wn;}}}if(f == -1)for(int i = 0;i < n;++i)cs[i].re /= n; } int n,m; const int maxn = 1e5+7; char S[maxn],T[maxn]; int ans[maxn*4]; complex csA[maxn*4],csB[maxn*4]; #define pr(x) cout<<#x<<":"<<x<<endl void solve(char c){memset(csA,0,sizeof(csA));memset(csB,0,sizeof(csB));for(int i = 0;i < n;++i) csA[i] = complex(S[i]==c?1.0:0);for(int i = 0;i < m;++i) csB[i] = complex(T[i]==c?1.0:0);int len = 1;while(len < n) len<<=1;len <<= 1;FFT(csA,len,1);FFT(csB,len,1);for(int i = 0;i < len;++i) csA[i] = csA[i]*csB[i];FFT(csA,len,-1);for(int i = m-1;i < len;++i) {ans[i] += int(csA[i].re+0.5);};} char big(char c){if(c == 'R') return 'S';if(c == 'S') return 'P';if(c == 'P') return 'R'; } int main(){cin>>n>>m>>S>>T;for(int i = 0;i < m/2;++i) swap(T[i],T[m-1-i]);for(int i = 0;i < m;++i) T[i] = big(T[i]);solve('P');solve('S');solve('R');int mx = 0;for(int i = 0;i < n+m+1;++i) mx = max(mx,ans[i]);cout<<mx<<endl;return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Problem H Rock Paper Scissors,FFT的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国联通前三季度净利润 172.46 亿
- 下一篇: Spotify 第三季度营收 3200