Kirinriki
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 456 Accepted Submission(s): 160
disA,B=∑i=0n−1|Ai−Bn−1−i|
The difference between the two characters is defined as the difference in ASCII.
You should find the maximum length of two non-overlapping substrings in given string S, and the distance between them are less then or equal to m.
Each case begins with one line with one integers m : the limit distance of substring.
Then a string S follow.
Limits
T≤100
0≤m≤5000
Each character in the string is lowercase letter, 2≤|S|≤5000
∑|S|≤20000
題意:
給出字符串s,尋找其兩個長度相同且不重疊的子串,滿足其每位的ascil差值之和不大於m,且長度最長。
思路:
因爲字符串的長度爲5000,所以可以枚舉兩個子串的對稱軸,然後對其區間進行尺取法,這樣只需要o(n^2)的複雜度即可。
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <string>
- #include <cmath>
- #include <algorithm>
- #include <queue>
- #include <map>
- using namespace std;
- const int INF = 0x3f3f3f3f;
- const int maxn = 5010;
- char a[maxn], num[maxn];
- int m;
- int solve(int len)
- {
- int s = 0, t = 0, ans = 0, sum = 0;
- while (1)
- {
- while (sum + num[t] <= m && t < len)
- {
- sum += num[t];
- ans = max(t - s + 1, ans);
- t++;
- }
- sum -= num[s++];
- if (s >= len) break;
- }
- return ans;
- }
- int main()
- {
- int t;
- scanf("%d", &t);
- while (t--)
- {
- int len, res = 0;
- scanf("%d", &m);
- scanf("%s", a);
- len = strlen(a);
- for (int i = 0; i <= len; i++) //枚舉折的中點
- {
- int cnt = 0;
- for (int j = 1; j + i < len && i - j >= 0; j++) //枚舉奇數情況
- num[cnt++] = abs(a[j + i] - a[i - j]);
- res = max(res, solve(cnt));
- }
- for (int i = 0; i <= len; i++) //枚舉折的中點
- {
- int cnt = 0;
- for (int j = 1; j + i - 1 < len && i - j >= 0; j++) //枚舉偶數情況
- num[cnt++] = abs(a[j + i - 1] - a[i - j]);
- res = max(res, solve(cnt));
- }
- printf("%d\n", res);
- }
- return 0;
- }
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 5010;
char a[maxn], num[maxn];
int m;
int solve(int len)
{
int s = 0, t = 0, ans = 0, sum = 0;
while (1)
{
while (sum + num[t] <= m && t < len)
{
sum += num[t];
ans = max(t - s + 1, ans);
t++;
}
sum -= num[s++];
if (s >= len) break;
}
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int len, res = 0;
scanf("%d", &m);
scanf("%s", a);
len = strlen(a);
for (int i = 0; i <= len; i++) //枚舉折的中點
{
int cnt = 0;
for (int j = 1; j + i < len && i - j >= 0; j++) //枚舉奇數情況
num[cnt++] = abs(a[j + i] - a[i - j]);
res = max(res, solve(cnt));
}
for (int i = 0; i <= len; i++) //枚舉折的中點
{
int cnt = 0;
for (int j = 1; j + i - 1 < len && i - j >= 0; j++) //枚舉偶數情況
num[cnt++] = abs(a[j + i - 1] - a[i - j]);
res = max(res, solve(cnt));
}
printf("%d\n", res);
}
return 0;
}