hdu1106 排序 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1106
字符处理+排序
题目分析:给你一串数,将其中的‘5’看成空格,去除前导0,按升序输出这些数(空格分隔)。
我的思路:我是这样想的,得到输入的这一串数(字符形式存)从第一个字符开始,一个一个的处理,处理完一个删一个,然后再处理后一个。输入的数可分三种:0、5、else。5作隔断,0作前导时要去掉,比较特殊。但0比5特殊得多,因为0可能是数,跟else归为一类,所以在判断时要特别照顾。具体情况(全排列)有这几种:0后0、0后数、0后5、数后0、数后数、数后5、5后0、5后5、5后数。有些需要合并,有些可以删掉;这里的数就是除前导0和5之外的所有数,0均为前导0,数字0归为数。在代码实现时保证5不出现在最前,去掉后三种情况。那么只剩0后数(作前导)、0后5、数后数、数后5 四种了。
以下是代码:
#include <iostream>
#include <string>
#include <cmath>
#include <string.h>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[])
{
char ch[10]={0};
string c;
int pos,p; //pos给int数组用 p给待处理char[]用
while (cin>>c)
{
int a[1000]={0};
pos=0;
p=0;
while (c[0])
{
if(c[0]=='5')c.erase(0,1);
else if (c[0]=='0'&&c[1]!='5')
{
if (ch[0])
{
ch[p]=c[0]; //存上最后一个数
c.erase(0,2);
for (int i=0;i<strlen(ch);i++) //处理待处理字符串
{
a[pos]+=(ch[i]-'0')*(int)pow(10.0,i);
}
pos++;
//cout<<"hello!"<<a[pos-1]<<endl;
ch[0]=0; //重要的判断for数,0,5
p=0; //处理完之后p回0
}
else c.erase(0,1); //0后0
}
else if (c[0]=='0'&&(c[1]=='5'||c[1]==0)) //0后5
{
a[pos]=0;
pos++;
//cout<<"pellow!"<<endl<<a[pos-1]<<endl;
c.erase(0,2);
}
else //if (c[1]=='5') //数后5
{
for(int i=0;c[0]!='5'&&c[0]!=0;i++)
{
ch[i]=c[0];
c.erase(0,1);
}
c.erase(0,1);
for (int i=strlen(ch)-1;i>=0;i--) //处理待处理字符串
{
a[pos]+=(ch[strlen(ch)-1-i]-'0')*(int)pow(10.0,i);
}
pos++;
//cout<<"hello!"<<endl;
memset(ch,0,10); //重要的判断for数,0,5
p=0; //处理完之后p回0
/*ch[p]=c[0]; //存上最后一个数
c.erase(0,2);
for (int i=0;i<strlen(ch);i++) //处理待处理字符串
{
a[pos]+=(ch[i]-'0')*(int)pow(10.0,i);
}
pos++;
cout<<"hello!"<<endl;
ch[0]=0; //重要的判断for数,0,5
p=0; //处理完之后p回0*/
}
/*else //数后数
{
ch[p]=c[0];
p++;
c.erase(0,1);
}*/
//cout<<c<<endl;
}
sort(a,a+pos);
for (int i=0;i<pos;i++)
{
cout<<a[i];
if(i<pos-1)cout<<' ';
}
cout<<endl;
}
return 0;
}
PS:这题看似容易,实际上trick也不少,新手做会有少许难度。
还有,在这个题我的代码中很重要的一部分是string.erase(pos,n);函数。做完这个题后,算是会了这个函数的一个用法了。有空再学另两种。
校OJ出了这道题,粘代码居然wrong!?自己重写了一个,明显成熟多了……
code:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int a[1000],i,pos,p;
char c[1050];
while(scanf("%s",c)!=EOF)
{
memset(a,0,sizeof(a));
pos=strlen(c);
p=0;
while(pos--&&pos>=0)
{
if(c[pos]=='5')continue;
else
{
for(i=1;c[pos]!='5'&&pos>=0;i*=10,pos--)
{
a[p]+=(c[pos]-'0')*i;
//printf("这是在里面的循环:pos==%d",pos);
}
p++;
}
//printf("这是在外面的循环:pos==%d",pos);
}
sort(a,a+p);
for(i=0;i<p;i++)
{
if(i)printf(" ");
printf("%d",a[i]);
}
printf("\n");
}
}
思路:从后向前找要方便得多,字符只有两种,'5'和数字,具体处理参看code↑。