题解 P3880 【[JLOI2008]提示问题】
_StarBird_ · · 题解
题解 P3880 【[JLOI2008]提示问题】
题目传送门
在博客中食用更佳
大 膜 你!
这题,没什么好说的,就是模拟。
我们考虑,把每一个提示都单独放在一个模块,一个一个处理就好了。
提示1
简单的将所有字母换成'.'即可
题目说简单,貌似也挺简单的,扫一遍字符串,把字母换成'.'就好惹。
另外,这个模块反正要扫一遍字符串,可以做个辅助,统计一下字母的个数。
code:
void hint1()
{
sum=0;
for(int i=0;i<len;++i)//遍历字符串
if (str[i]>='a' && str[i]<='z' || str[i]>='A' && str[i]<='Z') ++sum,printf(".");//如果找到字母,统计字母数并把字母换成.输出
else printf("%c",str[i]);//如果是普通的符号,就直接输出
puts("");//别忘了末尾换行
return;
}
提示2
从第1个提示而来,将所有字母的个数求出,再将总个数除以三,得到的最接近商的自然数
这里需要把总字母个数除以三再四舍五入,比较麻烦。
我们已经统计了字母的个数,所以可以手写一个四舍五入 (lz太菜,不会一些奇怪的函数,有会的评论下叭)。
这里可以用(int)number强制转换成(int)number+1为向下取整。
四舍五入代码如下:
int calc(double number)
{
if (number==(int)number) return (int)number;//如果两数相等,说明除出来是个整数
if (number-(int)number<(int)number+1-number) return (int)number;//如果这个数与向下取整的差小于向上取整的差,则应该向下取整
else return (int)number+1;//否则(这个数与向上取整的差小于向下取整的差),则应该向上取整
//怎样,是不是很玄学?(huaji
}
好了,废了那么多笔墨,我们完成了四舍五入。
接下来,就简单了:把字符串扫一遍,取前
code:
void hint2()
{
int mark=calc(1.0*sum/3);//去除四舍五入后的三分之一,注意要*1.0转double
int total=0;//字母数量
for(int i=0;i<len;++i)
if (str[i]>='a' && str[i]<='z' || str[i]>='A' && str[i]<='Z')
{
++total;
if (total==mark) pos=i;//记录三分之一中最后一个字母的位置
if (total<=mark) printf("%c",str[i]);//还没到三分之一且是字母,把原字符输出
else printf(".");//在三分之一线以后的字母,化为'.'输出
}
else printf("%c",str[i]);//是普通字符,则直接输出
puts("");
return;
}
提示3
从第2个提示而来,将剩下的元音字母显示。假如没有可显示的元音字母,则从第1个提示而来,即我们将前2/3的字母显示(同样如不能被3整除则取最接近的整数)
这个提示分两步:首先要判断有没有可显示的元音字母,如果没有,就要扫一遍整个字符串,取前
由于
判断元音字母的函数,应该比较好写(唱跳rap篮球+C+V就好惹):
bool check(char ch)
{
if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u' || ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U') return 1;//没啥好说的,判断就完事了
return 0;
}
扫一遍,也没什么难度,写完,这题就差不多了。
void hint3()
{
bool flag=0;//是否有元音字母
for(int i=pos+1;i<len;++i)//从上次的三分之一线后开始扫
if (check(str[i])) {flag=1;break;}//扫到了元音字母就记录
if (flag)//元音字母
{
for(int i=0;i<=pos;++i) printf("%c",str[i]);//先把三分之一线以前的字符输出
for(int i=pos+1;i<len;++i)//找三分之一线之后的元音字母
if (str[i]>='a' && str[i]<='z' || str[i]>='A' && str[i]<='Z')//字母
{
if (check(str[i])) printf("%c",str[i]);//元音字母正常输出
else printf(".");//辅音字母换成.输出
}
else printf("%c",str[i]);//普通字符直接输出
}
else//没有可输出的元音字母
{
int mx=calc(2.0*sum/3);//找到三分之二线
int total=0;
for(int i=0;i<len;++i)
for(int i=0;i<len;++i)
if (str[i]>='a' && str[i]<='z' || str[i]>='A' && str[i]<='Z')
{
++total;//统计字母的个数
if (total<=mx) printf("%c",str[i]);//小于三分之二线直接输出
else printf(".");
}
else printf("%c",str[i]);//超过了三分之二线则化成'.'输出
}
puts("");
return;
}
完成!
完整程序:
#include<bits/stdc++.h>
#define MAXN 60
using namespace std;
char str[MAXN];//字符串
int len,sum,pos;
int calc(double number)
{
if (number==(int)number) return (int)number;
if (number-(int)number<(int)number+1-number) return (int)number;
else return (int)number+1;
}
bool check(char ch)
{
if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u' || ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U') return 1;
return 0;
}
void hint1()
{
sum=0;
for(int i=0;i<len;++i)
if (str[i]>='a' && str[i]<='z' || str[i]>='A' && str[i]<='Z') ++sum,printf(".");
else printf("%c",str[i]);
puts("");
return;
}
void hint2()
{
int mark=calc(1.0*sum/3);
int total=0;
for(int i=0;i<len;++i)
if (str[i]>='a' && str[i]<='z' || str[i]>='A' && str[i]<='Z')
{
++total;
if (total==mark) pos=i;
if (total<=mark) printf("%c",str[i]);
else printf(".");
}
else printf("%c",str[i]);
puts("");
return;
}
void hint3()
{
bool flag=0;
for(int i=pos+1;i<len;++i)
if (check(str[i])) {flag=1;break;}
if (flag)
{
for(int i=0;i<=pos;++i) printf("%c",str[i]);
for(int i=pos+1;i<len;++i)
if (str[i]>='a' && str[i]<='z' || str[i]>='A' && str[i]<='Z')
{
if (check(str[i])) printf("%c",str[i]);
else printf(".");
}
else printf("%c",str[i]);
}
else
{
int mx=calc(2.0*sum/3);
int total=0;
for(int i=0;i<len;++i)
if (str[i]>='a' && str[i]<='z' || str[i]>='A' && str[i]<='Z')
{
++total;
if (total<=mx) printf("%c",str[i]);
else printf(".");
}
else printf("%c",str[i]);
}
puts("");
return;
}
int main()
{
cin.getline(str,MAXN);//有空格不能用cin或scanf,要用getline或gets
len=strlen(str);//字符串长度
hint1();
hint2();
hint3();
return 0;
}
总结一下本题坑点:
1.输入有空格,cin和scanf很难用,最好用能读一行的来输入
2.四舍五入很麻烦
3.有元音字母不需要输出
4.元音字母的判断
完