Gym 101775H(dp)
传送门
题面:
H. Mr. Panda and Birthday Song
time limit per test
3.0 s
memory limit per test
256 MB
input
standard input
output
standard output
Mrs. Panda’s birthday is coming. Mr. Panda wants to compose a song as gift for her birthday.
It is known that Mrs. Panda does not like a song if and only if its lyrics contain X vowels in a row, or Y consonants in a row (Otherwise, Mrs. Panda likes the song). The letters 'a', 'e', 'i', 'o', 'u' are vowels, and all others are consonants.
Though Mr. Panda is a gifted singer, he is bad at composing lyrics. Mr. Panda wants the song to be special. Thus, he searched Google for a template for lyrics of the song.
The template consists of lowercase English letters and possibly question marks. For example, "happybirthday" (without quotes, the same below), "????ybirthday" are valid templates but neither "happy birthday" nor "HappyBirthday" is. Mr. Panda needs to substitute all the question marks with lowercase English letters so that it becomes actual lyrics of the song.
Mr. Panda wants to give a surprise to Mrs. Panda. So, Mr. Panda hopes to compose not only a song from the template that Mrs. Panda likes but also a song from the same template that Mrs. Panda dislikes.
Because Mr. Panda is really bad at composing lyrics, even with a template, the task has confused him for days. Luckily, Mr. Panda knows you are in the contest and wants to ask you for help.
For a given template, output either "DISLIKE" (without quotes, the same below) if Mrs. Panda dislikes all the songs that are generated from the template (that means you cannot substitute letters for question marks so that Mrs. Panda likes the song), "LIKE" if Mrs. Panda likes all the songs that are generated from the template, or "SURPRISE" if Mr. Panda can compose a song Mrs. Panda likes and another song Mrs. Panda dislikes.
Input
The first line of the input gives the number of test cases, an integer T. T test cases follow.
Each test case consists of a line containing a string S, the template that Mr. Panda gets, an integer X, the minimum number of continuous vowels that Mrs. Panda dislikes, and an integer Y, the minimum number of continuous consonants that Mrs. Panda dislikes. In the template S, each character can be either one of lowercase English letters ('a’ to 'z’) or question mark ('?’).
- 1 ≤ T ≤ 300.
- 2 ≤ |S| ≤ 106.
- 1 ≤ X ≤ |S|.
- 1 ≤ Y ≤ |S|.
- Sum of |S| over all test cases ≤ 5 × 107.
Output
For each test case, output one line containing "Case #x: y", where x is the test case number (starting from 1) and y can be either "LIKE", "DISLIKE" or "SURPRISE" as mentioned in the problem description.
Example
input
Copy
5
happybirthda? 3 4
happybirth?ay 3 5
happybirthd?y 3 5
hellow?rld 3 5
helllllowooorld 3 5
output
Copy
Case #1: DISLIKE
Case #2: LIKE
Case #3: SURPRISE
Case #4: SURPRISE
Case #5: DISLIKE
题意:
给你一个长度不大于1e6的字符串(由,'a'-'z'或‘?’组成,且‘?’可转化为任意小写字母),以及两个数x,y。
现在有两个条件:
1)字符串中存在任意一个长度为x的子串均为元音,或存在任意一个长度为y的子串均为子串。
2)字符串中存在任意一个长度为x的子串不都是元音,且存在任意一个长度为y的子串不都是辅音。
如果同时满足条件(1)(2),则输出SURPRISE;如果只满足(1),则输出(DISLIKE);如果只满足(2),则输出(LIKE)。
题解:
首先,对于方案(1),我们遍历一遍整个字符串,在‘?’的条件下,默认将元音和辅音的连续数都+1,并记录最大值判断即可。
因此,我们只需要考虑如何处理出第二种情况。首先我们可以判断,因为要求任意一个连续的元音/辅音小于x/y,因此我们考虑要使得他们连续的尽可能小。
因此我们考虑用dp对此进行维护。我们设dp[i][0/1],(0代表元音,1代表辅音)为位于第i号的结点时最小的连续的元音/辅音的个数。
对于某个位置的字符倘若为元音,倘若之前的状态为连续元音,则此需要将连续元音的数量+1;而倘若之前的状态为连续辅音,则此时需要将连续元音的数量重新置为1。
对于某个位置的字符为辅音的情况同理。
而对于某个位置为‘?’的情况如果之前的状态为连续的元音,则此时可以将辅音清零;如果之前的状态为连续的辅音,则此时可以将元音清零。之后只需要不断维护他们的最小值即可。倘若发现在某一个状态下,连续元音数超过x,连续辅音数超过y,则证明不满足条件(2)。
代码:
#include <bits/stdc++.h>
#define maxn 1000005
using namespace std;
int dp[maxn][2];
char str[maxn];
int x,y;
bool judge(char c){
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u') return 1;
else return 0;
}
int main()
{
int t;
int Case=0;
scanf("%d",&t);
while(t--){
scanf("%s",str);
scanf("%d%d",&x,&y);
int len=strlen(str);
int vow=0,cons=0;
int maxv=0,maxc=0;
for(int i=0;i<len;i++){
if(str[i]=='?'){
vow++,cons++;
maxv=max(maxv,vow);
maxc=max(maxc,cons);
continue;
}
if(judge(str[i])){
vow++;
maxv=max(vow,maxv);
cons=0;
}
else{
cons++;
maxc=max(maxc,cons);
vow=0;
}
}
int flag1=0,flag2=1;
if(maxv>=x||maxc>=y) flag1=1;
memset(dp,0x3f3f3f3f,sizeof(dp));
dp[0][1]=dp[0][0]=0;
for(int i=1;i<=len;i++){
if(str[i-1]=='?'){
if(dp[i-1][0]<x) {
dp[i][0]=dp[i-1][0]+1;
dp[i][1]=1;
}
if(dp[i-1][1]<y){
dp[i][1]=min(dp[i][1],dp[i-1][1]+1);
dp[i][0]=1;
}
}
else if(judge(str[i-1])){
if(dp[i-1][0]<x) dp[i][0]=dp[i-1][0]+1;
if(dp[i-1][1]<y) dp[i][0]=1;
}
else{
if(dp[i-1][1]<y) dp[i][1]=dp[i-1][1]+1;
if(dp[i-1][0]<x) dp[i][1]=1;
}
if(dp[i][0]>=x&&dp[i][1]>=y){
flag2=0;
break;
}
}
printf("Case #%d: ",++Case);
if(flag1&&flag2) puts("SURPRISE");
else if(flag1) puts("DISLIKE");
else if(flag2) puts("LIKE");
}
return 0;
}