P1953
所属题目:P1953 易语言
前置代码
- 判断字符是否是数字
绝对有用
- 使用
<cctype>中的int isdigit(int _C)函数- 自己写一个
bool isdigit(char Ch){return '0'<=Ch&&Ch<='9';}
- 判断输入结束
输入中没有给数据个数,需要判断输入文件是否结束。
cin做法
当cin读入EOF时会返回false
while(cin>>Str);
scanf()做法
scanf()遇到EOF会返回EOF
while(scanf("%s",Str)!=EOF);
- 判断读入的是否是数字
用来判断该测试点为情况1还是情况2。
cin做法
cin不像printf()那样灵活,得先依次判断Str是否全是数字。
bool Check()
{
cin>>Str;
for(int i=0;i<Str.length();i++)
if(!isdigit(Str[i]))
return false;
return true;
}
sscanf()做法
sscanf()就舒服多了。
int sscanf(char* _Src,char* _Format,...)返回成功读入了几个量。
利用这一点,我们先用scanf()读入Str,再用sscanf()把Str当做整数再读一遍。
如果成功,sscanf()返回了1,说明该测试点是情况2,否则是情况1。
bool Check()
{
scanf("%s",Str);
return sscanf(Str,"%d",&Num);
}
情况1
输入输出格式拆解
第一个输入
\(\sf\color{red}AStr\sf\color{blue}Num\sf\color{black}.\sf\color{orange}BStr\sf\color{green}CStr\) 或
\(\ \sf\color{red}AStr\sf\color{black}.\sf\color{orange}BStr\sf\color{blue}Num\sf\color{green}CStr\)
第 i 个输入
不用管 真的不用管!
第 i 个输出
\(\sf\color{red}AStr\sf\color{purple}Num+i\sf\color{black}.\sf\color{orange}BStr\sf\color{green}CStr\) 或
\(\ \sf\color{red}AStr\sf\color{black}.\sf\color{orange}BStr\sf\color{purple}Num+i\sf\color{green}CStr\)
- \(\sf\color{red}AStr\) -> 文件主名
- \(\sf\color{blue}Num\) -> 起始数字
- \(\sf\color{orange}BStr\) -> 输出1的后缀名
- \(\sf\color{green}CStr\) -> 输出2的后缀名
开拆
策略:用 A 来记录是否读过数字, B 来记录是否读到过 '.' , C 来记录数字在 '.' 的前面还是后面。输入 In 后,先把字符逐个移动到 AStr 里,如果 B ,就改往 BStr 里移动字符。把 '.' 置空, In 剩下的部分既是 Num 。
scanf("%s %s",In,CStr);
for(int i=0,a=0,b=0;i<strlen(In);i++)
if(isdigit(In[i])) A=true;
else if(In[i]=='.')
if(A) B=true,C=true,In[i]=' ';
else B=true,In[i]=' ';
else if(!B) AStr[a]=In[i],In[i]=' ',a++;
else BStr[b]=In[i],In[i]=' ',b++;
sscanf(In,"%d",&Num);
printf("%s\n%s\n%d",AStr,BStr,Num);
输出
根据 C 来判断是哪种格式。
int i=Num;
while(scanf("%s %s",In,In)!=EOF)
{
if(C) printf("%s%d.%s %s%d.%s\n",AStr,i,BStr,AStr,i,CStr);
else printf("%s.%s%d %s.%s%d\n",AStr,BStr,i,AStr,CStr,i);
i++;
}
情况2
输入输出格式拆解
第一个输入 没什么好说的
\(\sf\color{blue}Num\)
第二个输入
\(\sf\color{red}AStr1\color{blue}Num\color{black}.\color{orange}BStr1\ \color{red}AStr2\color{blue}Num\color{black}.\color{orange}BStr2\) 或 \(\sf\color{red}AStr1\color{black}.\color{orange}BStr1\color{blue}Num\ \color{red}AStr2\color{black}.\color{orange}BStr2\color{blue}Num\)
第 i 个输入
不用管 本来就是!
第 i 个输出
\(\sf\color{red}AStr1\color{purple}Num+i\color{black}.\color{orange}BStr1\color{red}AStr2\color{purple}Num+i\color{black}.\color{orange}BStr2\) 或 \(\sf\color{red}AStr1\color{black}.\color{orange}BStr1\color{purple}Num+i\ \color{red}AStr2\color{black}.\color{orange}BStr2\color{purple}Num+i\)
- \(\sf\color{red}AStr1\),\(\sf\color{red}AStr2\) -> 文件主名
- \(\sf\color{orange}BStr1\),\(\sf\color{orange}BStr2\) -> 后缀名
- \(\sf\color{blue}Num\) -> 起始数字
输入
输入第二行时需要边输入边分解边输出。
scanf("%d",&Start);
int l=2;
scanf("%s",In);
F1(0);
printf("%s%d%s ",Left[0],Start,Right[0]);
scanf("%s",In);
F1(1);
printf("%s%d%s\n",Left[1],Start,Right[1]);
开拆
与情况1差不多,甚至还简单一些。以数字做分割,前面的是 Left ,后面的是 Right 。 q 表示同一行第 q 个 AStr 。
void F1(int q)
{
isleft=true;
for(int i=0,j=0,k=0;i<strlen(In);i++)
if(isdigit(In[i]))
isleft=false;
else if(isleft)
Left[q][j]=In[i],j++;
else
Right[q][k]=In[i],k++;
}
输出
很简单,不多说。
Num++;//想一想,为什么?
while(scanf("%s %s",In,In)!=EOF)
{
printf("%s%d%s ",Left[0],Num,Right[0]);
printf("%s%d%s\n",Left[1],Num,Right[1]);
Num++;
}
完整代码
#define _INC_STDIO 0
#include<cstdio>
#include<cstring>
#include<cctype>
char In[22],AStr[22],BStr[22],CStr[22];
bool A,B,C;
int Num;
void Mode1()
{
scanf("%s",CStr);
for(int i=0,a=0,b=0;i<strlen(In);i++)
if(isdigit(In[i])) A=true;
else if(In[i]=='.')
if(A) B=true,C=true,In[i]=' ';
else B=true,In[i]=' ';
else if(!B) AStr[a]=In[i],In[i]=' ',a++;
else BStr[b]=In[i],In[i]=' ',b++;
sscanf(In,"%d",&Num);
while(scanf("%s %s",In,In)!=EOF)
{
if(C) printf("%s%d.%s %s%d.%s\n",AStr,Num,BStr,AStr,Num,CStr);
else printf("%s.%s%d %s.%s%d\n",AStr,BStr,Num,AStr,CStr,Num);
Num++;
}
}
char Left[2][22],Right[2][22];
void F1(int q)
{
bool D=true;
for(int i=0,j=0,k=0;i<strlen(In);i++)
if(isdigit(In[i]))
D=false;
else if(D)
Left[q][j]=In[i],j++;
else
Right[q][k]=In[i],k++;
}
void Mode2()
{
scanf("%d",&Num);
scanf("%s",In);
F1(0);
printf("%s%d%s ",Left[0],Num,Right[0]);
scanf("%s",In);
F1(1);
printf("%s%d%s\n",Left[1],Num,Right[1]);
Num++;
while(scanf("%s %s",In,In)!=EOF)
{
printf("%s%d%s ",Left[0],Num,Right[0]);
printf("%s%d%s\n",Left[1],Num,Right[1]);
Num++;
}
}
int main()
{
scanf("%s",In);
if(sscanf(In,"%d",&Num)==0)
Mode1();
else
Mode2();
return 0;
}
不要尝试直接复制,可能会有玄学错误
成功压进 100ms(94ms)
完结散花
PCwqyy

浙公网安备 33010602011771号