题解 P2555 【[AHOI2002]数的朗读】
Victorique · · 题解
见过的最恶心的模拟
这个题题意非常明白,思路非常清晰,做法非常单一,但是就是很难做。。要注意的细节远远超乎预料。
各种细节的注意直接扔到代码里了,貌似也没有什么非常的地方和关键代码。实际上是因为处处都是关键代码。。。。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int z,flag,o,l,n,l1,d=-1,k,book,yi;
char ch[1001],ch1[101],shu[5];
int main()
{
shu[1]='S';
shu[2]='B';
shu[3]='Q';//这里的处理可以凭个人喜好,我个人比较喜欢这么处理,后面也比较简洁。
cin>>ch;//不要想当然的一个个读,正常情况下好像没问题,但是0一多就会错了,老老实实直接全读进来比较好,也可以用循环从1开始读入,有强迫症的自便。
l=strlen(ch);
for(int i=0;i<l;i++)
{
if(ch[i]=='+'||ch[i]=='-'||ch[i]=='0')//仔细读题,不仅只有符号和前缀0,还有“+”这个坑货。。。。
{
o++;//o用来记录你读完这些字符一共用了多长。
}
if(ch[i]=='.')
{
d=i;
break;//如果前面全是0,又读到小数点,单独算一种情况。
}
}
if(o==l)//极端情况之一,全是0,不要觉得这个很多余,因为出现+0000000000000这样的数也不是不可能。。
{
cout<<"0";
return 0;
}
if(o==d)//这里就是第一种情况分支,如果是个小于1的小数,当成特殊情况处理。
{
cout<<"0";
flag=1;//进行标记。
}
if(d==-1)//如果压根没有读到小数点,把小数点的位置标记为第l位。
d=l;
if(flag==1)//特殊处理<1的情况
{
cout<<"D";
for(int i=o+1;i<l;i++)//从小数点下一位直接读到最后
{
cout<<ch[i];
}
return 0;
}else//处理不是<1的情况
{
if(ch[0]=='-')//如果有负号(题目规定一定是第一个字符),先读出来
{
cout<<"F";
k++;//当前读到的位数
}else
if(ch[0]=='+')//这个坑爹的+又出现了,必须特殊处理。。。。
k++;
while(ch[k]=='0')//处理掉所有的前缀0
k++;
for(int i=k;i<d;i++)
{
if(d-i>8)//如果此时剩下的位数多余8位,输出Y,数据保证不大于十亿,所以不用管之前有没有S什么的。
{
cout<<ch[i];
cout<<"Y";
continue;
}
if(d-i>5)//处理万级。
{
if(ch[i]!='0')//如果当前的数不是0,就要读出来
{
if(book==1)//如果之前的一位是0,读出来那个0
{
cout<<"0";
cout<<ch[i];
if(d-i-1!=0)
cout<<shu[d-i-4-1];//这就是用1,2,3标记的原因,这里很好处理。。。
book=0;//把标记取消
yi=1;//确定这个数大于一万并且有一个不是0的数。
}else
{
cout<<ch[i];//如果前面没有0直接输出就可以了
if(d-i-1!=0)//如果这个数减出来不是0,就输出后面的,防止输出无用空格。
cout<<shu[d-i-4-1];
yi=1;
}
}else
{
book=1;//打上标记。
}
continue;
}
if(d-i==5)//当读到万位时由于有W特殊处理
{
if(d-k>8&&yi==0)//如果这个数在10亿以上并且万级全是0
yi=0;//继续是0不用读了。
else
{
if(ch[i]!='0')//如果当前位不是0
{
if(book==1)//刚才的标记现在还可以用
{
cout<<"0";
cout<<ch[i];
cout<<"W";//把万读出来
book=0;
}else
{
cout<<ch[i];//直接读
cout<<"W";
}
}else//直接读W,打上标记。
{
cout<<"W";
book=1;
}
book=0;
continue;
}
}
if(d-i<=4)//千位一下的就很好处理了
{
if(ch[i]!='0')
{
if(book==1)
{
cout<<"0";
cout<<ch[i];
if(d-i-1!=0)
cout<<shu[d-i-1];
book=0;
}else
{
cout<<ch[i];
if(d-i-1!=0)
cout<<shu[d-i-1];
}
}else
{
book=1;
}
}
}
if(d!=l&&d!=l-1)//最后再处理一遍小数点。
{
cout<<"D";
for(int i=d+1;i<l;i++)
cout<<ch[i];//这才算真正结束了。
}
}
}
真是恶心的模拟
总而言之,这个题有耐心,总是能做出来的,毕竟什么高级算法都没用。。。。