1 条题解
-
0
自动搬运
来自洛谷,原作者为

StarBird
StarBird yydStarBird!搬运于
2025-08-24 21:53:41,当前版本为作者最后更新于2020-06-21 19:48:29,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题解 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个提示而来,将所有字母的个数求出,再将总个数除以三,得到的最接近商的自然数,将第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整除则取最接近的整数)
这个提示分两步:首先要判断有没有可显示的元音字母,如果没有,就要扫一遍整个字符串,取前的字母输出。
由于calc函数的帮助,实现起来应该也比较容易,就是判断元音字母的if有点长,菜鸡lz甚至单独写了函数……
判断元音字母的函数,应该比较好写(唱跳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.元音字母的判断
完
- 1
信息
- ID
- 2837
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者