Description
最近在JLOI网上的一个流行游戏中,选手要回答很难的问题。假如在规定时间内不能回答,系统将给出1个提示,之后再依次给出第2,3个提示。出现在答案中的是字母和下列字符:',' '.' ':' ';' '!' '?' '-' 和空格(空格不会在开头和结尾出现)
字母是指:小写字母'a'...'z' 大写字母 'A'...'Z',其中a e i o u A E I O U是元音字母。
生成提示的规则:
第1个提示:简单的将所有字母换成'.'即可;
第2个提示:从第1个提示而来,将所有字母的个数求出,再将总个数除以三,得到的最接近商的自然数N,将第1个提示中的前N个字母显示;
第3个提示:从第2个提示而来,将剩下的元音字母显示。假如没有可显示的元音字母,则从第1个提示而来,即我们将前2/3的字母显示(同样如不能被3整除则取最接近的整数)。
Input
仅一行,给出问题,问题字符数最多不超过50。
Output
三行:按规则输出的三行提示。
Sample Input
Upomoc! Lpv s nm pkrl sv smglsnk.
Sample Output
......! ... . .. .... .. ........
Upomoc! Lp. . .. .... .. ........
Upomoc! Lpv s nm pkrl s. ........
题目分析:
这道题就是那种十分钟写完代码 用一小时调各种bug 的题 QAQ
有两个地方需要注意:
- "如不能被3整除则取最接近的整数" 把 (double)x/3 和floor(x/3)+0.5 比较一下就好了。
- "前2/3的字母" 这个着实坑了我30分钟QAQ 。(where 变量 说明) 前2/3的字符不代表有前2/3的字母啊QAQ
再来解释 一个"奇技淫巧"
if(check(s[i])&&(++k)<=tmp)
难道每执行一次 if 语句 k都要++么? 是会结果造成影响的!!!
但事实上 && , || 运算符是有这样的法则的。当从前往后执行时遇到了一个值使得整个式子的结果固定(即后面的式子即使运行也不会对最终结果产生影响),那么就会停止判断后面的式子。
那么 当check(s[i])的返回值=false时,就会停止判断[(++k)<=tmp] k就不会++,直到check(s[i])=true 时 k才会++;
相反 如果是这样的话,
if((++k)<=tmp&&check(s[i]))
就会真的起到 每执行一次 if 语句 k都要++ 的效果
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
char s[1000];
char a[1000];
char b[1000];
char book[15]={0,'a','A','e','E','i','I','o','O','u','U'};
int len,temp;
int tmp;
int where;
int check(char x)
{
if(x>='a'&&x<='z') return 1;
if(x>='A'&&x<='Z') return 1;
return 0;
}
int check_yuan(char x)
{
for(int i=1;i<=10;i++)
if(x==book[i]) return 1;
return 0;
}
int check_flag()
{
int k=0;
for(int i=0;i<len;i++)
if(check(s[i])&&(++k)==tmp)
{
where=i;
break;
}
for(int i=where+1;i<len;i++)
if(check_yuan(s[i]))
return 1;
return 0;
}
void work1()
{
for(int i=0;i<len;i++)
if(check(s[i]))
a[i]='.',temp++;
else a[i]=s[i];
printf("%s\n",a);
}
void work2()
{
int k=0;
double nmp=temp;nmp/=3;
if(nmp-0.5<=temp/3) tmp=temp/3;
else tmp=temp/3+1;
for(int i=0;i<len;i++)
if(check(s[i])&&(++k)<=tmp)
b[i]=s[i];
else b[i]=a[i];
printf("%s\n",b);
}
void work3_true()
{
for(int i=0;i<len;i++)
if(i<=where) printf("%c",b[i]);
else
{
if(check_yuan(s[i])) printf("%c",s[i]);
else printf("%c",b[i]);
}
}
void work3_false()
{
int k=0;tmp=0;
double nmp=temp*1.0;
nmp=nmp*2/3;
if(nmp-0.5<=temp*2/3) tmp=temp*2/3;
else tmp=temp*2/3+1;
for(int i=0;i<len;i++)
if(check(s[i])&&(++k)<=tmp)
printf("%c",s[i]);
else printf("%c",a[i]);
}
int main()
{
gets(s);
len=strlen(s);
work1();
work2();
if(check_flag()) work3_true();
else work3_false();
}