Loading

P1953

所属题目:P1953 易语言

前置代码

  1. 判断字符是否是数字
    绝对有用
  1. 使用<cctype> 中的 int isdigit(int _C) 函数
  2. 自己写一个
bool isdigit(char Ch){return '0'<=Ch&&Ch<='9';}
  1. 判断输入结束
    输入中没有给数据个数,需要判断输入文件是否结束。
  1. cin 做法
    cin 读入 EOF 时会返回 false
while(cin>>Str);
  1. scanf()做法
    scanf()遇到 EOF 会返回 EOF
while(scanf("%s",Str)!=EOF);
  1. 判断读入的是否是数字
    用来判断该测试点为情况1还是情况2。
  1. cin 做法
    cin 不像 printf() 那样灵活,得先依次判断 Str 是否全是数字。
bool Check()
{
	cin>>Str;
	for(int i=0;i<Str.length();i++)
		if(!isdigit(Str[i]))
			return false;
	return true;
}
  1. 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 ,后面的是 Rightq 表示同一行第 qAStr

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)
完结散花

posted @ 2022-07-13 10:39  PCwqyy  阅读(6)  评论(0)    收藏  举报  来源