题意很好理解,但这道题实在太考细节了...
随便乱打的一个测试样例竟然帮我找到第八组测试样例过不去的原因??hhhh...
有个小地方忘写了导致第十组样例一直WA...
为各位dalao献上蒟蒻的代码,详情请看注释。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <cmath>
#include <queue>
#include <cmath>
#include <ctype.h>
#define ll long long
using namespace std ;
string str1 ; //输入的原始串
string str2 ; //根据第1个提示之后的串
string str3 ; //将第2个提示之后的串复制到str3中
//string str4 ; str4 ? 并没有 str4,由str3或str2与str1可直接得出最后一个提示的串
int tot_alpha ; //统计总共的字母数字
bool check = false ; //检查第3个提示中是否有可显示的元音字母
int indexx ; //找到第2个提示第N个字母的位置
int closest(double a , double b , double c){ //在第二个提示中比较谁更接近,也可如上面几位dalao的round函数
if ( fabs(c - a) > fabs(c - b) ){ //比较浮点数绝对值,谁小谁更接近
return b ;
}
return a ;
}
void display_one(){ //提示1,直接处理字符串
str2 = str1 ;
for ( int i = 0 ; i < str1.size() ; i ++ ){
if ( isalpha(str2[i]) ){
str2[i] = '.' ;
tot_alpha ++ ;
}
}
cout << str2 << endl ;
return ;
}
void display_two(){ //提示2,由str1和str2组合而成
double number = tot_alpha / 3.0 ;
/*天花板ceil(element) 和 地板函数floor(element) (雾
ceil()向上取整,返回不小于element的最大的整数,
floor()向下取整,返回不大于element的最小的整数
*/
int num = closest(ceil(number) , floor(number) , number) ; //找到离商最接近的自然数N
int count_ = 0 ; //记录到目前出现的字母个数
for ( int i = 0 ; i < str1.size() ; i ++ ){
str3[i] = str1[i] ; //将串复制到str3,便于第三个提示的处理 *ps:之前觉得这个str3会用到,但写到后面发现没什么用...于是一直WA第十组样例的噩梦开始了...
/*纪念找到这个BUG的此组胡乱敲打的样例....
input: asd132asd123zxc
output: ...132...123...
output: asd132...123...
output: as.132a..123... 正确输出-> output: asd132a..123...
所以有了之后的 “用不着str3” 的疯狂打脸...
*/
if ( isalpha(str1[i]) ){ //ctype.h 头文件判断字符是否是字母函数
cout << str1[i] ; //输出原串str1中的对应字符
count_ ++ ; //若真字母个数+1
}else {
cout << str1[i] ; //输出原串str1中的对应字符
}
if ( count_ == num ) { //当字母个数等于N时,记录下标,并跳出
indexx = i ; //记录第N个字母的位置
break ;
}
}
for ( int i = indexx + 1 ; i < str1.size() ; i ++ ){ //输出str2之后的串
str3[i] = str2[i] ;
cout << str2[i] ;
}
cout << endl ;
return ;
}
void display_thr(){
/*str3 = str1 ;
此处若加上这语句会出现一个未知的错误..
如果有dalao知道为什么请告诉我,感激不尽!
*/
for ( int i = indexx + 1 ; i < str1.size() ; i ++ ){
/*
cytpe.h头文件 tolower() 函数将一个字母转换成小写字母,与之对应的是 toupper()
此处统一转成小写字母,便于处理大写元音字母与小写元音字母
*/
if ( tolower(str1[i]) == 'a' || tolower(str1[i]) == 'e' || tolower(str1[i]) == 'i' || tolower(str1[i]) == 'o' || tolower(str1[i]) == 'u' ){
check = true ; //说明有可显示的元音字母
}
}
if ( check ){ //若真,则由原串str1和str3组合生成答案
for ( int i = 0 ; i < indexx ; i ++ ){ //输出到第N个字母的位置
cout << str1[i] ;
}
for ( int i = indexx ; i < str1.size() ; i ++ ){
/*输出第N个字母之后的字符,并判断是否有元音字母,
若有则输出str1中的字母,若无则输出str3中的字符
*/
if ( tolower(str1[i]) == 'a' || tolower(str1[i]) == 'e' || tolower(str1[i]) == 'i' || tolower(str1[i]) == 'o' || tolower(str1[i]) == 'u' ){
cout << str1[i] ;
}else{
cout << str3[i] ;
}
}
}else{ //若非真,则由原串str1与str2组合生成答案
double number = tot_alpha / 3.0 * 2.0 ;
int count_ = 0 ;
int num = closest(ceil(number) , floor(number) , number) ;
for ( int i = 0 ; i < str1.size() ; i ++ ){
if ( count_ < num ){ //显示前2/3个字母
if ( isalpha(str1[i]) ){
cout << str1[i] ;
count_ ++ ;
}else{
cout << str1[i] ;
}
}
else{ //若字母个数等于num则输出str2之后的串
cout << str2[i] ;
}
}
}
return ;
}
int main(){
getline(cin , str1) ;
str3 = str1 ; //若不加上此句在 codeblocks 下会返回非零...如果有dalao知道是什么原因请告诉我,感激不尽!
display_one() ;
display_two() ;
display_thr() ;
return 0 ;
}