https://codeforc.es/gym/101775/problem/H
题意
- 连续出现元音长度 >= x || 连续出现辅音长度 >= y ,输出
DISLIKE。 - 连续出现元音长度 < x && 连续出现辅音长度 <y,输出
LIKE。 - 即满足1又满足2,输出
SURPRISE。
题解
对于1,直接贪心求最大的连续元音/辅音次数,即遇到?时,元/辅音都+1。
对于2,采用dp。
0: 元音,1:辅音
设
d
p
[
i
]
[
0
/
1
]
dp[i][0/1]
dp[i][0/1]:到第i位时连续的元/辅音最小长度。
状态转移:
- ch == 元音
d p [ i ] [ 0 ] = d p [ i − 1 ] [ 0 ] + 1 , d p [ i ] [ 1 ] = 0 dp[i][0] = dp[i-1][0]+1,dp[i][1] = 0 dp[i][0]=dp[i−1][0]+1,dp[i][1]=0 - ch == 辅音
d p [ i ] [ 1 ] = d p [ i − 1 ] [ 1 ] + 1 , d p [ i ] [ 0 ] = 0 dp[i][1] = dp[i-1][1]+1,dp[i][0] = 0 dp[i][1]=dp[i−1][1]+1,dp[i][0]=0 - ch == ?
如果dp[i-1][0]+1 < x,那么便可以把?变成元音
d p [ i ] [ 0 ] = d p [ i − 1 ] [ 0 ] + 1 , d p [ i ] [ 1 ] = 0 dp[i][0] = dp[i-1][0]+1,dp[i][1] = 0 dp[i][0]=dp[i−1][0]+1,dp[i][1]=0
否则
只能是辅音 d p [ i ] [ 1 ] = 1 dp[i][1] = 1 dp[i][1]=1
如果dp[i-1][1]+1 < y,那么便可以把?变成辅音
d p [ i ] [ 1 ] = m i n ( d p [ i ] [ 1 ] , d p [ i − 1 ] [ 1 ] + 1 ) , d p [ i ] [ 0 ] = 0 dp[i][1] = min(dp[i][1],dp[i-1][1]+1),dp[i][0] = 0 dp[i][1]=min(dp[i][1],dp[i−1][1]+1),dp[i][0]=0
否则
只能是元音 d p [ i ] [ 0 ] = 1 dp[i][0] = 1 dp[i][0]=1
只要遇到 d p [ i ] [ 1 ] > = y dp[i][1] >= y dp[i][1]>=y && d p [ i ] [ 0 ] > = x dp[i][0] >= x dp[i][0]>=x,那就不可行。
代码
#include <bits/stdc++.h>
using namespace std;
#define FOR0(a,b) for(int i = a; i < b; ++i)
#define FORE(a,b) for(int i = a; i <= b; ++i)
typedef long long ll;
typedef pair<int,int> pii;
/*
0: 元音 1: 辅音
dp[i][0/1]: 到第i位为止连续 元音/辅音 最小的个数
if(ch == 元音) {
dp[i][0] = dp[i-1][0]+1;
dp[i][1] = 0;
}
if(ch == 辅音) {
dp[i][1] = dp[i-1][1]+1;
dp[i][0] = 0;
}
if(ch == ?) {
if(dp[i-1][0]+1 < x) {
dp[i][0] = dp[i-1]+1
dp[i][1] = 0;
} else
dp[i][1] = 1;
if(dp[i-1][1]+1 < y) {
dp[i][1] = min(dp[i][1],dp[i-1][1]+1);
dp[i][0] = 0;
} else
dp[i][0] = 1;
}
*/
const int maxn = 1e6+5;
char s[maxn];
int dp[maxn][2];
bool ok(char ch) {
return ch == 'a' || ch == 'e' || ch == 'i' || ch =='o' || ch == 'u';
}
int main() {
int T;
scanf("%d", &T);
for(int kas = 1; kas <= T; ++kas) {
scanf("%s", s+1);
int n = strlen(s+1);
int x,y;
scanf("%d%d", &x, &y);
int yuan = 0, fu = 0;
int my = 0, mf = 0;
bool dislike = false, like = true;
for(int i = 1; i <= n; ++i) {
if(s[i] == '?') {
yuan++; fu++;
} else if(ok(s[i])) {
yuan++; fu = 0;
} else {
fu++; yuan = 0;
}
my = max(my,yuan);
mf = max(mf,fu);
}
if(my >= x || mf >= y) dislike = true;
memset(dp, 0x3f3f3f3f,sizeof dp);
dp[0][0] = dp[0][1] = 0;
for(int i = 1; i <= n; ++i) {
if(s[i] == '?') {
if(dp[i-1][0]+1 < x) {
dp[i][0] = dp[i-1][0]+1;
dp[i][1] = 0;
} else
dp[i][1] = 1;
if(dp[i-1][1]+1 < y) {
dp[i][1] = min(dp[i][1],dp[i-1][1]+1);
dp[i][0] = 0;
} else
dp[i][0] = 1;
} else if(ok(s[i])) {
dp[i][0] = dp[i-1][0]+1;
dp[i][1] = 0;
} else {
dp[i][1] = dp[i-1][1]+1;
dp[i][0] = 0;
}
if(dp[i][0] >= x || dp[i][1] >= y) {
like = false;
break;
}
}
printf("Case #%d: ", kas);
if(dislike && like)
puts("SURPRISE");
else if(dislike)
puts("DISLIKE");
else if(like)
puts("LIKE");
}
return 0;
}
2万+



被折叠的 条评论
为什么被折叠?



