题解 P1953【易语言】

· · 题解

社区里都说是大模拟,不过自己感觉还好,我自己写的就1.28k。写这题时我正陷入某杀的泥潭中,在好友的建议下决定先把这题切了涨了点信心。结果先A了某杀才A了这题

题目分析

操作流程:

  1. 读入一个字符串IN。如果IN是文件名而不是01(直接看IN[0]即可),读入一个字符串ANS,为目标文件名的格式。

  2. 读入两个字符串in,out,为格式。剩下的全部读进垃圾内存,但注意要记录文件名的数量n。令整数st为文件的起始编号

  3. 如果IN是文件名的话,将inout全部改成IN,从其中提取数字,处理出st,然后将out中的后缀改为ANS

  4. 如果IN不是文件名,直接将st设为IN代表的数字。

  5. 输出

代码

首先有一些功能函数:

del(s,u):将字符串s的第u位删除

void del(char* s,int u){for(int i=u;s[i];++i) s[i]=s[i+1];} 

精准覆盖

find(s,l,r):在字符串s中找到第一个介于[l,r]之间的字符,没找到返回-1。如果找单个字符c可以find(s,c,c)

int find(char* s,char l,char r)
{
    for(int i=0,sz=strlen(s);i<sz;++i)
        if(s[i]>=l&&s[i]<=r) return i;
    return -1;
}

output(s,n):将代表文件名的字符串s中的编号修改为n,并输出。

void output(char* s,int n)
{
    int p=find(s,'0','9');
    while(isdigit(s[p+1])) del(s,p+1);
    for(int i=0;i<p;++i) putchar(s[i]);
    printf("%d",n);
    for(int i=p+1,sz=strlen(s);i<sz;++i) putchar(s[i]);
}

于是代码就很简单了。

根据上面的步骤,1&2:

    scanf("%s",IN); 
    if(IN[0]!='1'&&IN[0]!='0') scanf("%s",ANS);
    scanf("%s%s",in,out);
    while(~scanf("%s%s",tmp,tmp)) ++n;

3:

void solve()
{
    memcpy(in,IN,sizeof(IN));
    memcpy(out,IN,sizeof(IN));
    int p1,p2=find(out,'0','9'),x=out[p2]-'0';
    while(isdigit(out[p2+1])){x=x*10+out[p2+1]-48;del(out,p2+1);}//计算st 留下p2作为数字标识符
    p1=find(out,'.','.');//找到分隔点
    for(int i=p1+1,sz=strlen(out);i<sz;++i) out[i]=0;//先清空
    for(int i=0,sz=strlen(ANS);i<sz;++i) out[i+1+p1]=ANS[i];//再拷贝
    if(p2>p1) out[strlen(out)]='0';//数字在扩展名 补上已被清除的数字标识符
    st=x;
}
//in main()
if(IN[0]!='1'&&IN[0]!='0') solve();

4:

    else st=IN[0]-'0';

5:

void output(char* s,int n)
{
    int p=find(s,'0','9');//找到数字标识符
    while(isdigit(s[p+1])) del(s,p+1);//删除多余数字 留p标识
    for(int i=0;i<p;++i) putchar(s[i]);
    printf("%d",n);
    for(int i=p+1,sz=strlen(s);i<sz;++i) putchar(s[i]);
}
// in main()
    for(int i=0;i<n;++i)
    {
        //输出两个文件名 别忘了编号+st
        output(in,i+st); 
        putchar(' ');
        output(out,i+st);
        puts("");
    }

全部代码就不放了。

后记:此文写于切掉某棋后不久。感觉此题相比某杀和某棋这种大型模拟,或是某复杂度这种中型模拟,真是小巫见大巫了。只能算是和龙虎斗一个级别的小型模拟。(毕竟我这std才49行)

\texttt{The End.}