首先,这次练习感觉很无奈啊,不能用stl,让本来简单的问题变得有些复杂了。
排序的话,快排的效率应该是最高的吧,现成的函数不能用,那么只能手写了,先贴一下手写的快排吧
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[50];
void qs(int begin,int end)
{
if(begin>end)return;
int l=begin,r=end;
int key=a[begin];
while(l<r)
{
while(a[r]>=key&&l<r)r--;
swap(a[l],a[r]);
while(a[l]<=key&&l<r)l++;
swap(a[l],a[r]);
}
qs(begin,l-1);
qs(r+1,end);
}
int main()
{
int n;
while(cin>>n)
{
for(int i=0;i<n;i++)cin>>a[i];
qs(0,n-1);
for(int i=0;i<n;i++)cout<<a[i]<<" ";
cout<<endl;
}
return 0;
}
首先第一题,有奇数个数,找出出现次数超过(n+1)/2的那个,思路很简单,排序,输出中间那个数,我首先是用选择排序试了下,果断t了,接着就考虑发挥上面代码的功效,结果也奇葩的T了,这让我很是头疼,赛后用sort交了下,ac了。也想过标记数的出现次数,但是map不能用,又觉得开数组标记不现实,所以没尝试,但赛后发现这种方法是可行的,数据较水。在oj上原题的discuss里,看到了一种好方法,没有涉及排序,个人感觉很牛掰,感觉自己的思路过于局限了,这是那方法的代码:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n,m,num,s;
while(scanf("%d",&n)!=EOF)
{
num=0;
for(int i=0;i<n;i++)
{
scanf("%d",&m);
if(num==0)
{
s=m;
num++;
}
else
{
if(m!=s)num--;
else num++;
}
}
printf("%d\n",s);
}
return 0;
}
第二题,显然较水,随便排下就过了。
第三题也不难,这里感觉考的不是排序,而是熟练的拆分字符串将其转化为数字,只要思路清晰,基本不难。
第四题,是关于时钟指针夹角的排序,总共就5个值排序,所以这里的排序并不是重点,重点是理解角度怎么算,题目中输入的时间采取的是24小时制的,而大家知道时钟一圈是12小时,这里就涉及到相关转换。总之理解了题意,ac并不难,就是题目读的很麻烦,在比赛时间内未能ac。。。。。。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int t;
double am,ah;
struct node
{
double h,m,hh,angle;
} p[5],temp;
char ss;
int main()
{
scanf("%d",&t);
while(t--)
{
for(int i=0; i<5; i++)
{
cin>>p[i].h>>ss>>p[i].m;
if(p[i].h>12)p[i].hh=p[i].h-12;
else p[i].hh=p[i].h;
am=p[i].m*6;
ah=p[i].hh*30+p[i].m/2.0;
p[i].angle=ah>am?ah-am:am-ah;
if(p[i].angle>180)p[i].angle=360.0-p[i].angle;
//cout<<ah<<" "<<am<<" "<<p[i].angle<<endl;
}
for(int i=0; i<3; i++)
{
for(int j=i+1; j<5; j++)
{
if(p[i].angle>p[j].angle)
{
temp=p[i];
p[i]=p[j];
p[j]=temp;
}
else if(p[i].angle==p[j].angle)
{
if(p[i].h>p[j].h)
{
temp=p[i];
p[i]=p[j];
p[j]=temp;
}
else if(p[i].h==p[j].h)
{
if(p[i].m>p[j].m)
{
temp=p[i];
p[i]=p[j];
p[j]=temp;
}
}
}
}
}
if(p[2].h<10)cout<<"0"<<p[2].h;
else cout<<p[2].h;
cout<<":";
if(p[2].m<10)cout<<"0"<<p[2].m<<endl;
else cout<<p[2].m<<endl;
}
return 0;
}
第五题,考的是结构体排序,这道题让我很是窝火啊,明明不难,但我各种wa,还找不出原因,让我蛋蛋碎了一地的感觉啊,最后还是用sort过的。。。。。。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,g,fen[15],num,k,ans;
struct node
{
string name;
int sum;
}p[1005],temp;
bool cmp(node x,node y)
{
if(x.sum==y.sum)return x.name<y.name;
else return x.sum>y.sum;
}
int main()
{
while(scanf("%d",&n)&&n)
{
ans=0;
scanf("%d%d",&m,&g);
for(int i=1;i<=m;i++)scanf("%d",&fen[i]);
for(int i=0;i<n;i++)
{
cin>>p[i].name;
scanf("%d",&num);
p[i].sum=0;
for(int j=0;j<num;j++)
{
scanf("%d",&k);
p[i].sum+=fen[k];
}
if(p[i].sum>=g)ans++;
}
/*for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
if(p[i].sum<p[j].sum)
{
temp=p[i];
p[i]=p[j];
p[j]=temp;
}
else if(p[i].sum==p[j].sum)
{
if(p[i].name>p[j].name){
temp=p[i];
p[i]=p[j];
p[j]=temp;}
}
}
if(p[i].sum>=g)ans++;
else break;
}*/
sort(p,p+n,cmp);
printf("%d\n",ans);
for(int i=0;i<ans;i++)
{
cout<<p[i].name;
printf(" %d\n",p[i].sum);
}
}
return 0;
}
第六题,先是对于n个数俩俩组合成 N*(N-1)/2个数再排序,输出前m大的数。组合后数蛮多的,排序起来也不好办(特别是在不能stl的情况下)。。。最后是记录数的个数,过的。。。。对于群邮里的正解我没怎么看懂。。。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[1000001],a[3001];
int n,m,ma,num;
void solve()
{
printf("%d",ma);
f[ma]--;
m--;
for(int i=ma;i>=0;i--)
{
if(f[i])
{
while(f[i]--)
{
printf(" %d",i);
m--;
if(!m)return;
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(f,0,sizeof(f));
ma=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=n-1;i>0;i--)
{
for(int j=i-1;j>=0;j--)
{
num=a[i]+a[j];
f[num]++;
if(num>ma)ma=num;
}
}
solve();
printf("\n");
}
return 0;
}
第七题纯粹找规律,哪要排序啊。。。。
第八题也较水,手写快排飘过。