LuoguP3880 [JLOI2008]提示问题 题解
Content
由于题目要求是在太过复杂,请见原题面查看。
Solution
这题明显是一个大模拟,那么废话少说,我们开始吧。
首先就是要找到所有的字母,比如说样例,其中底下加了^ 号的就是所有字母的位置:
Upomoc! Lpv s nm pkrl sv smglsnk.
^^^^^^ ^^^ ^ ^^ ^^^^ ^^ ^^^^^^^
把它们的位置存下来,然后就可以输出第一个提示了——直接将所有字母替换成 . 即可。
自然而然地,字母出现的次数 \(cnt\) 也可以模拟得出来了。然后,我们就可以求出来前 \(\dfrac{1}{3}\) 和前 \(\dfrac{2}{3}\) 的字母的位置了。
然后,我们先从 \(\dfrac{1}{3}\) 的字母出现的位置开始找起,一直到字符串末尾,如果有元音,那么第三个提示就只输出 \(\dfrac{1}{3}\) 的字母的位置之前的所有字符以及之后的所有元音字母,否则输出 \(\dfrac{2}{3}\) 的字母的位置之前所有的字符。
至于第二个提示就不用再说了吧,直接输出 \(\dfrac{1}{3}\) 的字母的位置之前所有的字符即可。
那么这道题目就算做完了,作为省选题算是很水的(毕竟这是 10 多年以前了)。
Code
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
string s;
int pk[57];
map<int, int> pk2;
int main() {
getline(cin, s);
int len = s.size();
for(int i = 0; i < len; ++i)
if((s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= 'a' && s[i] <= 'z')) {
pk[++pk[0]] = i; //将字母出现的位置记录下来
pk2[i] = pk[0];
printf(".");
} else printf("%c", s[i]);
puts("");
int key1 = floor(pk[0] / 3.0 + 0.5), key2 = floor((pk[0] * 2) / 3.0 + 0.5), vowel = 0;
// printf("%d %d\n", key1, key2);
for(int i = 0; i < len; ++i)
if(pk2[i] >= 1 && pk2[i] <= key1) printf("%c", s[i]);
else if(pk2[i]) printf(".");
else printf("%c", s[i]);
puts("");
for(int i = pk[key1] + 1; i < len; ++i)
if(s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u' || s[i] == 'A' || s[i] == 'E' || s[i] == 'I' || s[i] == 'O' || s[i] == 'U') {
vowel = 1;
break;
}
if(vowel) {
for(int i = 0; i < len; ++i)
if(pk2[i] >= 1 && pk2[i] <= key1) printf("%c", s[i]);
else if(s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u' || s[i] == 'A' || s[i] == 'E' || s[i] == 'I' || s[i] == 'O' || s[i] == 'U') printf("%c", s[i]);
else if(pk2[i]) printf(".");
else printf("%c", s[i]);
} else {
for(int i = 0; i < len; ++i)
if(pk2[i] >= 1 && pk2[i] <= key2) printf("%c", s[i]);
else if(pk2[i]) printf(".");
else printf("%c", s[i]);
}
}

浙公网安备 33010602011771号