3.算法分析与排序
A - SORT AGAIN HDU - 2523 (哈希)
给你N个整数,x1,x2…xn,任取两个整数组合得到|xi-xj|,(0<i,j<=N,i!=j)。
现在请你计算第K大的组合数是哪个(一个组合数为第K大是指有K-1个不同的组合数小于它)。
Input
输入数据首先包含一个正整数C,表示包含C组测试用例.
每组测试数据的第一行包含两个整数N,K。(1<N<=1000,0<K<=2000)
接下去一行包含N个整数,代表x1,x2…xn。(0<=xi<=2000)
Output
对于每组测试数据,请输出第K大的组合数,每个输出实例占一行。
Sample Input
3
3 2
4 0 7
4 2
1 2 3 4
2 1
2 9
Sample Output
4
2
7
//一开始想着用set挺方便的,但是一直超时....
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <cstdio>
using namespace std;
int b[2020];
int a[2020];
int main()
{
int c;
cin>>c;
while(c--)
{
int n,k;
cin>>n>>k;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
b[abs(a[i]-a[j])]++;
}
}
int cnt=0;
for(int i=0;i<2020;i++)
{
if(b[i]>0) cnt++;
if(cnt==k)
{
cout<<i<<endl;
break;
}
}
}
}
B - sort HDU - 1425
给你n个整数,请按从大到小的顺序输出其中前m大的数。
Input
每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。
Output
对每组测试数据按从大到小的顺序输出前m大的数。
Sample Input
5 3
3 -35 92 213 -644
Sample Output
213 92 3
//cin、cout会超时
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n,m;
int a[1000010];
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(a,0,sizeof(a));
for(int i=0;i<n;i++) scanf("%d",&a[i]);//cin>>a[i];
sort(a,a+n,cmp);
printf("%d",a[0]);
for(int i=1;i<m;i++) printf(" %d",a[i]);// cout<<' '<<a[i];
printf("\n");
}
return 0;
}
C - 前m大的数 HDU - 1280
还记得Gardon给小希布置的那个作业么?(上次比赛的1005)其实小希已经找回了原来的那张数表,现在她想确认一下她的答案是否正确,但是整个的答案是很庞大的表,小希只想让你把答案中最大的M个数告诉她就可以了。
给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它们两两相加得到的N*(N-1)/2个和,求出其中前M大的数(M<=1000)并按从大到小的顺序排列。
Input
输入可能包含多组数据,其中每组数据包括两行:
第一行两个数N和M,
第二行N个数,表示该序列。
Output
对于输入的每组数据,输出M个数,表示结果。输出应当按照从大到小的顺序排列。
Sample Input
4 4
1 2 3 4
4 5
5 3 6 4
Sample Output
7 6 5 5
11 10 9 9 8
//与A题很像,但A题是无重复数字,C题有,所以sort排一下就行了(不知道为么子把数组b换成vector会超时)
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std;
int a[3333],b[10000000];
int cnt;
bool cmp(int x,int y)
{
return x>y;
}
int main()
{
int n,m;
while((scanf("%d%d",&n,&m)!=EOF))
{
cnt=0;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
b[cnt]=a[i]+a[j];
cnt++;
}
}
sort(b,b+cnt,cmp);
printf("%d",b[0]);
for(int i=1;i<m;i++)
printf(" %d",b[i]);
printf("\n");
}
return 0;
}
F - PM2.5 HDU - 5182 (多关键字排序)
一个长方形有长和宽,分别设为 a 和 b
现在想对一些长方形进行排序
有一种新的排序方法。如下
我们按照两个长方形的a-b值来对他们按降序排序,如果有重复,按照b值升序排序,如果还有重复,按照输入的顺序排序。
也就是说,是多关键字排序:
第1关键字,a-b,降序;
第2关键字,b,升序;
第3关键字,输入的顺序,升序;
Input
多组测试数据(大概100组),每一组测试数据第一行先给出一个整数n,代表有n个长方形需要被排序。
长方形被从0到n−1标号。
接下来n行,每一含有两个整数代表每一个长方形a和b 第i行描述长方形i−1的信息。
请处理到文件末尾。
所有整数都在[1,100]的范围内
Output
对于每一个数据,在一行中输出排好序之后的长方形ID,注意每两个 ID 【之间!】有一个空格,其他地方不要有多余空格
Sample Input
2
100 1
1 2
3
100 50
3 4
1 2
Sample Output
0 1
0 2 1
#include <iostream>
#include <vector>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
struct Rec
{
int num;
int a;
int b;
int cha;
}rec[111];
bool cmp(Rec r1,Rec r2)
{
if(r1.cha!=r2.cha) return r1.cha>r2.cha;
else
{
if(r1.b!=r2.b) return r1.b<r2.b;
else return r1.num<r2.num;
}
}
int main()
{
int n;
while(cin>>n)
{
int a,b;
for(int i=0;i<n;i++)
{
cin>>rec[i].a>>rec[i].b;
rec[i].num=i;
rec[i].cha=rec[i].a-rec[i].b;
}
sort(rec,rec+n,cmp);
cout<<rec[0].num;
for(int i=1;i<n;i++)
{
cout<<" "<<rec[i].num;
}
cout<<endl;
}
return 0;
}