[JLOI2008]提示问题

题目传送门

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
有两个地方需要注意:

  1. "如不能被3整除则取最接近的整数"  把 (double)x/3 和floor(x/3)+0.5 比较一下就好了。
  2. "前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();
}

发表评论

邮箱地址不会被公开。 必填项已用*标注