洛谷【题解】P1098 字符串的展开

一道大水题。。。黄色的纯模拟到现在也只见了一次
先放上传送门吧

原题传送门

首先写这道题之前,要先普及以下ASCII码。。。(这忒么简单了)
每一个字符都有自己的ASCII码值,例如A的ASCII码值就是65
计算ASCII码值的方法

	char a;            //要计算ASCII码值的字符
	int b;               //存放ASCII码值
	cin>>a;
	b=int(a);        //强制转换,就能达到求ASCII码值的目的
	cout<<b;

将数字转换为字符也十分简单,只需将程序倒一倒

	int a;                  //要求这个字符的ASCII码值
	char b;              //存放字符
	cin>>a;
	b=char(a);       //强制转换
	cout<<b;

好了,言归正传:
这道模拟题耗费了我一个星期的时间。。。主要是毒瘤的数据点。有些数据点在题目中完全没有讲到,让我浪费了5次下载测试数据的机会。。。
先来讲一下题意吧:
输入:
输入三个参数 p1,p2,p3,输入一串字符串。

输出(按7种情况输出):
将减号替换成下面7种情况:

(1)关于参数p1(以后其他参数的例子全部是用p1=1这个参数)
当p1=1时,当减号右边的字母的ASCII码大于减号左边字母的ASCII码时,按照26字母的顺序,将减号替换成左边字母到右边字母中间的所有小写字母
例:a-d 输出为abcd
当p1=2时,把p1=1中的替换出的小写字母转换为大写字母
例:a-d 输出为aBCd
当p1=3时,把p1=1中的替换出的小写字母转换为星号
例:a-d 输出为a**d

(2)关于参数p2
参数p2较简单,当p2=k时,在p1中所有替换的字符重复输出k次。
例:a-d p2=2 输出为abbccd

(3)关于参数p3
参数p3也十分简单。
当p3=1时,不改变所有输出方式,也就是完全不用管
当p3=2时,输出的所有字符倒叙输出
例:a-d p2=1,p3=2 输出为acbd

(4)当在字符串开头出现减号时,无论多少个,都重新输出这些减号
(5)当减号两边的两个字母相同时,输出两个字母中间夹着减号
(6)当减号右边的字符的ASCII码刚好是左边字符ASCII码的值+1,输出两个字符
(7)当减号左边的字符的ASCII码大于右边字符的ASCII码,输出两个字符夹着减号
(8)如果减号左右两边一边是数字,一边是字母,输出两个字符夹着减号

有了这些就好了,我们就可以写出一个大模拟###…

以下先奉上代码

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
char a[233];
int p1,p2,p3;
void turn(char b,char c)
{
	if((int(b))==(int(c)-1))
    {
        return;
    }
    if(int(c)<=int(b))
    {
        cout<<"-";
        return;
    }
    if((int(b)>=48)&&(int(b)<=57))
    {
        if(int(c)>=65)
        {
            cout<<"-";
            return;
        }
    }
    if((int(c)>=48)&&(int(c)<=57))
    {
        if(int(b)>=65)
        {
            cout<<"-";
            return;
        }
    }
    if(p1==3)
    {
        int k=int(c)-int(b)-1;
        for(int i=0;i<k;i++)
        {
            for(int j=0;j<p2;j++)
            {
                cout<<"*";
            }
        }
        return;
    }
    if((int(b)>=48)&&(int(b)<=57))
    {
        if((int(c)>=48)&&(int(c)<=57))
        {
            if(int(b)>=(int(c)))
            {
                cout<<"-";
                return;
            }
            else
            {
                for(int i=(int(b)+1);i<(int(c));i++)
                {
                    for(int j=0;j<p2;j++)
                    {
                        cout<<(i-'0');
                    }
                }
            }
        }
        return;
    }
    if((p1==1)&&(p3==1))
    {
        for(int i=(int(b)+1);i<(int(c));i++)
        {
            for(int j=0;j<p2;j++)
            {
                if(i<97)
                {
                    cout<<char(i+32);
                }
                else cout<<char(i);
            }
        }
    }
    if((p1==1)&&(p3==2))
    {
        for(int i=(int(c)-1);i>(int(b));i--)
        {
            for(int j=0;j<p2;j++)
            {
                if(i<97)
                {
                	cout<<char(i+32);
                }
                else cout<<char(i);
            }
        }
    }
    if((p1==2)&&(p3==1))
    {
        for(int i=(int(b)+1);i<(int(c));i++)
        {
            for(int j=0;j<p2;j++)
            {
            	if(i>97)
            	{
            		cout<<char(i-32);
                }
                else cout<<char(i);
            }
        }
    }
    if((p1==2)&&(p3==2))
    {
        for(int i=(int(c)-1);i>(int(b));i--)
        {
            for(int j=0;j<p2;j++)
            {
                if(i>97)
                {
                	cout<<char(i-32);
                }
                else cout<<char(i);
            }
        }
    }
}
int main()
{
    scanf("%d %d %d",&p1,&p2,&p3);
    scanf("%s",a);
    int len=strlen(a);
    for(int i=0;i<len;i++)
    {
    	if(((a[i]=='-')&&(i==0))||((a[i]=='-')&&((a[i-1]=='-')||(a[i+1]=='-'))))
    	{
    		cout<<"-";
    		continue;
        }
        if(a[i]!='-')
        {
            printf("%c",a[i]);
        }
        else turn(a[i-1],a[i+1]);
    }
    return 0;
}

这个代码最关键的点就是turn函数了,包含了以上7种情况,写的我心力交瘁。。。
现在一个个来按照情况拆分吧

	if((int(b))==(int(c)-1))
    {
        return;
    }
    if(int(c)<=int(b))
    {
        cout<<"-";
        return;
    }
    if((int(b)>=48)&&(int(b)<=57))
    {
        if(int(c)>=65)
        {
            cout<<"-";
            return;
        }
    }
    if((int(c)>=48)&&(int(c)<=57))
    {
        if(int(b)>=65)
        {
            cout<<"-";
            return;
        }
    }

以下的for和if都是最外层的,里面的会单独说

第一个if:对应点6,右边ASCII是左边ASCII+1
第二个if:对应点5和点7:左边大于或等于
第三、四个if:对应点(8),左右两边不是同类

	if(p1==3)
    {
        int k=int(c)-int(b)-1;
        for(int i=0;i<k;i++)
        {
            for(int j=0;j<p2;j++)
            {
                cout<<"*";
            }
        }
        return;
    }
    //当p1=3时,就可以直接填充星号
    if((int(b)>=48)&&(int(b)<=57))
    {
        if((int(c)>=48)&&(int(c)<=57))
        {
            if(int(b)>=(int(c)))
            {
                cout<<"-";
                return;
            }
            else
            {
                for(int i=(int(b)+1);i<(int(c));i++)
                {
                    for(int j=0;j<p2;j++)
                    {
                        cout<<(i-'0');
                    }
                }
            }
        }
        return;
    }
    //当左右两边都是数字时,判断,如果右>左,直接输出,不然按要求输出
    if((p1==1)&&(p3==1))
    {
        for(int i=(int(b)+1);i<(int(c));i++)
        {
            for(int j=0;j<p2;j++)
            {
                if(i<97)
                {
                    cout<<char(i+32);
                }
                else cout<<char(i);
            }
        }
    }
    if((p1==1)&&(p3==2))
    {
        for(int i=(int(c)-1);i>(int(b));i--)
        {
            for(int j=0;j<p2;j++)
            {
                if(i<97)
                {
                	cout<<char(i+32);
                }
                else cout<<char(i);
            }
        }
    }
    if((p1==2)&&(p3==1))
    {
        for(int i=(int(b)+1);i<(int(c));i++)
        {
            for(int j=0;j<p2;j++)
            {
            	if(i>97)
            	{
            		cout<<char(i-32);
                }
                else cout<<char(i);
            }
        }
    }
    if((p1==2)&&(p3==2))
    {
        for(int i=(int(c)-1);i>(int(b));i--)
        {
            for(int j=0;j<p2;j++)
            {
                if(i>97)
                {
                	cout<<char(i-32);
                }
                else cout<<char(i);
            }
        }
    }
    //最后就是枚举每一种情况,然后按要求输出

这就是p1参数的恐怖之处了。。。
虽然代码长,但是能AC啊

    for(int i=0;i<len;i++)
    {
    	if(((a[i]=='-')&&(i==0))||((a[i]=='-')&&((a[i-1]=='-')||(a[i+1]=='-'))))
    	{
    		cout<<"-";
    		continue;
        }
        if(a[i]!='-')
        {
            printf("%c",a[i]);
        }
        else turn(a[i-1],a[i+1]);
    }

最后,主函数里面的第一个if语句一定要下,不然就又WA了。。。

谢谢大家!

猜你喜欢

转载自blog.csdn.net/tidongCrazy/article/details/92008512