本文主要是介绍Codeforces Gym 101667H (UVA Live 8095) Rock Paper Scissors (FFT) -2017 Daejeon Regional,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目传送门
Problem H
Rock Paper Scissors
Time Limit: 1 Second
There is a Rock Paper Scissors (RPS) machine which generates Rock, Paper, or Scissors randomly. You also have a similar small Rock Paper Scissors machine. Before the game, the RPS machine will generate a list of its choice of Rock, Paper, or Scissors of the length ݊ and your machine also will generates a list of its choice of the length ݉. That is, you know the whole list of the RPS’s choices and you have the list of your machine’s choices. Of course, each choice of the machines is one of the three options (Rock, Paper, or Scissors).
Now, you start playing Rock Paper Scissors game. In every match, you compare the list of RPS’s choice and the list of your machine’s in sequence and decide whose machine would win. However, only you may skip some RPS’s choices to find the position to get the most winning points of your machine. After you decide to start match you cannot skip the match till the end of the match. ‘R’ stands for Rock, ‘P’ stands for Paper, and‘S’ stands for Scissors.
For example, suppose that the RPS’s list is “RSPPSSSRRPPR” and your machine’s list is “RRRR”. To get the most winning points, you should start the match after skipping three RPS’s choices or four RPS’s choices.(See Figure H.1.) Then, you can win in three matches. The draw case is not considered.
Given the list of RPS’s choices and the list of your choices, find the position to get the maximum number of wining matches.
Input
Your program is to read from standard input. The first line contains two positive integers ݊ and ሺ1 ݉ ൏݊ 100,000ሻ, where ݊ is the length of the string for RPS machine and ݉ is the length of the string for your machine.
Following the first line contains the list of choices of RPS machine and the second line contains thelist of choices of your machine.
Output
Your program is to write to standard output. The first line should contain an integer indicating the maximum number of wining matches. The following shows sample input and output for four test cases.
给两个仅由RPS构成的字符串,长短不一,问你把短串从长串某个位置开始一一匹配字符,最多可以匹配多少位。
可以对每一种字符单独计算答案,把字符匹配的过程看做卷积和,则当前要匹配的字符对应1,否则为0,把其中一个串反转,就只要算这两个01数列的卷积和即可。
利用FFT算出每种字符匹配对答案的贡献,最后相加取最大值即可。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn = 400005, inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const ld pi = acos(-1.0L);
char s[maxn], t[maxn];
int n1, n2, m;struct complex
{double r, i;complex(double _r = 0, double _i = 0){r = _r; i = _i;}complex operator +(const complex &b){return complex(r + b.r, i + b.i);}complex operator -(const complex &b){return complex(r - b.r, i - b.i);}complex operator *(const complex &b){return complex(r*b.r - i * b.i, r*b.i + i * b.r);}
};
complex conj(complex a) {return complex(a.r, -a.i);
}
complex a[maxn], b[maxn];
int ans[maxn];struct fff {int n, rev[maxn];complex o[maxn], oi[maxn];void init(int m) {n = 1;int k = 0;mem0(rev); mem0(o); mem0(oi);while (n < m) n <<= 1, k++;for (int i = 0; i < n; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (k - 1));for (k = 0; k < n; k++) {o[k] = complex(cos(2 * pi / n * k), sin(2 * pi / n * k));oi[k] = conj(o[k]);}}void fft(complex *a, complex *w) {for (int i = 0; i < n; i++)if (i < rev[i]) swap(a[i], a[rev[i]]);for (int l = 2; l <= n; l <<= 1) {int m = l >> 1;for (complex *p = a; p != a + n; p += l)for (int k = 0; k < m; k++) {complex t = w[n / l * k] * p[k + m];p[k + m] = p[k] - t;p[k] = p[k] + t;}}}void dft(complex *a, int f) {if (f == 1) fft(a, o); else {fft(a, oi);for (int i = 0; i < n; i++) a[i].r /= n;}}void mul(complex *a, complex *b, int m) {init(m);dft(a, 1); dft(b, 1);for (int i = 0; i < n; i++) a[i] = a[i] * b[i];dft(a, -1);}
};
fff f;void cal(char c) {mem0(a); mem0(b);for (int i = 0; i < n1; i++) if (s[i] == c) a[i].r = 1; else a[i].r = 0;for (int i = 0; i < n2; i++) if (t[i] == c) b[i].r = 1; else b[i].r = 0;f.mul(a, b, m);for (int i = 0; i < m; i++) ans[i] += floor(a[i].r + 0.5);
}int main() {int i, j;scanf("%d%d", &n1, &n2);scanf("%s", s); scanf("%s", t);m = n1 + n2 - 1;for (i = 0; i < n1; i++) {if (s[i] == 'R') s[i] = 'P'; elseif (s[i] == 'P') s[i] = 'S'; else s[i] = 'R';}strrev(t);cal('R'); cal('P'); cal('S');int ANS = -1;;for (i = n2-1; i < m; i++) ANS = max(ANS, ans[i]);printf("%d\n", ANS);
// system("pause");return 0;
}
这篇关于Codeforces Gym 101667H (UVA Live 8095) Rock Paper Scissors (FFT) -2017 Daejeon Regional的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!