1.hdu 1106 快速排序
时间复杂度最好O(n*logn),最差O(n*n),如果原来的序列越是有顺序,那么时间复杂度就越高。
Who's in the Middle
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 19585 Accepted Submission(s): 8635
Problem Description
FJ is surveying his herd to find the most average cow. He wants to know how much milk this 'median' cow gives: half of the cows give as much or more than the median; half give as much or less.
Given an odd number of cows N (1 <= N < 10,000) and their milk output (1..1,000,000), find the median amount of milk given such that at least half the cows give the same amount of milk or more and at least half give the same or less.
Given an odd number of cows N (1 <= N < 10,000) and their milk output (1..1,000,000), find the median amount of milk given such that at least half the cows give the same amount of milk or more and at least half give the same or less.
Input
* Line 1: A single integer N
* Lines 2..N+1: Each line contains a single integer that is the milk output of one cow.
* Lines 2..N+1: Each line contains a single integer that is the milk output of one cow.
Output
* Line 1: A single integer that is the median milk output.
Sample Input
5 2 4 1 3 5
Sample Output
3HintINPUT DETAILS: Five cows with milk outputs of 1..5 OUTPUT DETAILS: 1 and 2 are below 3; 4 and 5 are above 3.
Source
Recommend
#include<cstdio>
#include<iostream>
using namespace std;
int n, m;
const int maxn = 1000000;
int a[maxn + 10];
void qs(int L, int R)
{
if (L >= R) return;
int le = L, ri = R;
int t = a[le];
while (le < ri)
{
while (le < ri&&a[ri] >= t) ri--;
a[le] = a[ri];
while (le < ri&&a[le] <= t) le++;
a[ri] = a[le];
}
a[le] = t;
qs(L, le - 1);
qs(le + 1, R);
}
int main()
{
std::ios::sync_with_stdio(false);
while(cin>>n)
{
for (int i = 1; i <= n; i++) cin >> a[i];
qs(1, n);
//for (int i = n; i >= n - m + 1; i--)
//{
// printf("%d%c", a[i], i == n - m + 1 ? '\n' : ' ');
//}
cout << a[(n>>1)+1] << endl;
}
return 0;
}
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI (4.0*atan(1.0))
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson ind<<1,le,mid
#define rson ind<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
#define ysk(x) (1<<(x))
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn=10000+20 ;
//const int maxm= ;
int a[maxn];
void quick_sort(int le,int ri)
{
if(le>=ri) return;
int st=le,ed=ri;
int t=a[st];
int prin=a[st];
while(st<ed)
{
while(st<ed&&a[ed]>=prin) ed--;
a[st]=a[ed];
while(st<ed&&a[st]<=prin ) st++;
a[ed]=a[st];
}
a[st]=prin;
int mid=(le+ri)>>1;
quick_sort(le,st-1);
quick_sort(st+1,ri);
}
int n;
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
quick_sort(1,n);
// for(int i=1;i<=n;i++)
// cout<<a[i]<<" ";
// cout<<endl;
cout<<a[n/2+1]<<endl;
}
return 0;
}
堆排序:
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn = 10000;
int n,a[maxn + 10];
#define for1(a,n) for(int (a)=1;(a)<=(n);(a)++)
void heapAdjust(int pos, int ed)
{
int val = a[pos];
while (pos*2 <=ed)
{
int nex = pos << 1;
if (nex+ 1 <= ed&& a[nex] < a[nex + 1]) nex++;
if (val >= a[nex]) break;
a[pos] = a[nex];
pos = nex;
}
a[pos] = val;
}
void heapSort()
{
for (int i =n/2;i>=1;i-- ) heapAdjust(i, n);
for (int i = n; i > 1; i--)
{
swap(a[i], a[1]);
heapAdjust(1, i - 1);
}
}
int main()
{
std::ios::sync_with_stdio(false);
while (cin>>n)
{
for1(i, n) cin >> a[i];
heapSort();
/*for1(i, n) printf("%d ", a[i]);
putchar('\n');*/
printf("%d\n", a[(n>>1)+1]);
}
}
2.hdu 1106 插入排序
时间复杂度O(n*n),
最好情况O(n),最坏O(n*n);
平均O(n*n);
排序
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 45475 Accepted Submission(s): 13039
Problem Description
输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数就是0)。
你的任务是:对这些分割得到的整数,依从小到大的顺序排序输出。
你的任务是:对这些分割得到的整数,依从小到大的顺序排序输出。
Input
输入包含多组测试用例,每组输入数据只有一行数字(数字之间没有空格),这行数字的长度不大于1000。
输入数据保证:分割得到的非负整数不会大于100000000;输入数据不可能全由‘5’组成。
输入数据保证:分割得到的非负整数不会大于100000000;输入数据不可能全由‘5’组成。
Output
对于每个测试用例,输出分割得到的整数排序的结果,相邻的两个整数之间用一个空格分开,每组输出占一行。
Sample Input
0051231232050775
Sample Output
0 77 12312320
Source
Recommend
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI (4.0*atan(1.0))
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson ind<<1,le,mid
#define rson ind<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
#define ysk(x) (1<<(x))
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
//const int maxn= ;
//const int maxV=200+10 ;
char s[1050];
vector<int >a;
int main()
{
while(~scanf("%s",s))
{
a.clear();
a.push_back(0);
int i=0;
while(s[i])
{
int now=0;bool has=0;
for(;s[i]&&s[i]!='5';i++)
{
has=1;
now=now*10+s[i]-'0';
}
if(has) a.push_back(now);
while(s[i]&&s[i]=='5') i++;
}
/* while(s[i])
{
int now=0;
for(;s[i]&&s[i]!='5';i++) //可能一开始就是5,所以这样写看似正确,实则有漏洞
{
now=now*10+s[i]-'0';
}
a.push_back(now);
while(s[i]&&s[i]=='5') i++;
}
*/
int n=a.size()-1;
for(int i=2;i<=n;i++) if(a[i]<a[i-1])//a[0]作为监视哨,可以用t来代替代码中的a[0],带式要多写一个条件判定是否到达终点,所以用a[0]更方便。
{
a[0]=a[i];
a[i]=a[i-1];
int j=i-2;
for( ;a[0]<a[j] ;j--)
{
a[j+1]=a[j];
}
a[j+1]=a[0];
}
printf("%d",a[1]);
for(int i=2;i<=n;i++)
printf(" %d",a[i]);
putchar('\n');
}
return 0;
}
设有n个元素
比较次数 | 移动次数(赋值次数) | |
最好情况 | (i) ∑1 (2<=i<=n) =n-1 | (i)∑0 (2<=i<=n) =0 |
最坏情况 | (i)∑ i (2<=i<=n) =(n+2)*(n-1)/2 (对与-0<=j<i都要比较) | (i) ∑(i+1) (2<=i<=n) = (n+4)*(n-1)/2
(对于第i个元素 的位置调整, 最多有i-1个 元素后移 (a[0]不会), a[0]复制为 a[i]算一次, a[i]放进去算一次,总共i+2次) |
3.希尔排序:hdu 1872
稳定排序
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4295 Accepted Submission(s): 1687
Problem Description
大家都知道,快速排序是不稳定的排序方法。
如果对于数组中出现的任意a[i],a[j](i<j),其中a[i]==a[j],在进行排序以后a[i]一定出现在a[j]之前,则认为该排序是稳定的。
某高校招生办得到一份成绩列表,上面记录了考生名字和考生成绩。并且对其使用了某排序算法按成绩进行递减排序。现在请你判断一下该排序算法是否正确,如果正确的话,则判断该排序算法是否为稳定的。
如果对于数组中出现的任意a[i],a[j](i<j),其中a[i]==a[j],在进行排序以后a[i]一定出现在a[j]之前,则认为该排序是稳定的。
某高校招生办得到一份成绩列表,上面记录了考生名字和考生成绩。并且对其使用了某排序算法按成绩进行递减排序。现在请你判断一下该排序算法是否正确,如果正确的话,则判断该排序算法是否为稳定的。
Input
本题目包含多组输入,请处理到文件结束。
对于每组数据,第一行有一个正整数N(0<N<300),代表成绩列表中的考生数目。
接下来有N行,每一行有一个字符串代表考生名字(长度不超过50,仅包含'a'~'z'),和一个整数代表考生分数(小于500)。其中名字和成绩用一个空格隔开。
再接下来又有N行,是上述列表经过某排序算法以后生成的一个序列。格式同上。
对于每组数据,第一行有一个正整数N(0<N<300),代表成绩列表中的考生数目。
接下来有N行,每一行有一个字符串代表考生名字(长度不超过50,仅包含'a'~'z'),和一个整数代表考生分数(小于500)。其中名字和成绩用一个空格隔开。
再接下来又有N行,是上述列表经过某排序算法以后生成的一个序列。格式同上。
Output
对于每组数据,如果算法是正确并且稳定的,就在一行里面输出"Right"。如果算法是正确的但不是稳定的,就在一行里面输出"Not Stable",并且在下面输出正确稳定排序的列表,格式同输入。如果该算法是错误的,就在一行里面输出"Error",并且在下面输出正确稳定排序的列表,格式同输入。
注意,本题目不考虑该排序算法是错误的,但结果是正确的这样的意外情况。
注意,本题目不考虑该排序算法是错误的,但结果是正确的这样的意外情况。
Sample Input
3 aa 10 bb 10 cc 20 cc 20 bb 10 aa 10 3 aa 10 bb 10 cc 20 cc 20 aa 10 bb 10 3 aa 10 bb 10 cc 20 aa 10 bb 10 cc 20
Sample Output
Not Stable cc 20 aa 10 bb 10 Right Error cc 20 aa 10 bb 10
Author
linle
Source
Recommend
错解:为什么?因为希尔排序是不稳定的啊!!!
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI (4.0*atan(1.0))
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson ind<<1,le,mid
#define rson ind<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
#define ysk(x) (1<<(x))
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn=300+20 ;
//const int maxV=200+10 ;
int n;
vector<int >ve;
struct A
{
string name;
int score;
}a[maxn];
void shellinsert(int delta)
{
for(int i=delta+1;i<=n;i++) if(a[i-delta].score<a[i].score )
{
a[0]=a[i];
a[i]=a[i-delta];
int j;
for( j=i-2*delta;j>0&&a[j].score<a[0].score;j-=delta)
a[j+delta]=a[j];
a[j+delta]=a[0];
}
}
void shellsort( )
{
for(int i=0;i<ve.size();i++)
{
int delta=ve[i];
shellinsert(delta);
}
}
int main()
{
ve.clear();
ve.push_back(17);
ve.push_back(13);
ve.push_back(7);
ve.push_back(5);
ve.push_back(3);
ve.push_back(1);
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
cin>>a[i].name>>a[i].score;
}
shellsort();
bool right=1,stable=1;
string s;int sc;
for(int i=1;i<=n;i++)
{
cin>>s>>sc;
if(sc!=a[i].score) right=0;
if(s!=a[i].name) stable=0;
}
if(right&&stable) {puts("Right");continue;}
puts( right ?"Not Stable":"Error") ;
for(int i=1;i<=n;i++)
{
cout<<a[i].name<<" "<<a[i].score<<endl;
}
}
return 0;
}
正解:
(注:快排也是不稳定的)
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI (4.0*atan(1.0))
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson ind<<1,le,mid
#define rson ind<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
#define ysk(x) (1<<(x))
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn=300+20 ;
//const int maxV=200+10 ;
int n;
vector<int >ve;
struct A
{
string name;
int score;
int index;
bool operator<(const A y)const
{
if(score!=y.score) return score>y.score;
return index<y.index;
}
}a[maxn];
int main()
{
ve.clear();
ve.push_back(17);
ve.push_back(13);
ve.push_back(7);
ve.push_back(5);
ve.push_back(3);
ve.push_back(1);
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
cin>>a[i].name>>a[i].score;
a[i].index=i;
}
sort(a+1,a+1+n);
bool right=1,stable=1;
string s;int sc;
for(int i=1;i<=n;i++)
{
cin>>s>>sc;
if(sc!=a[i].score) right=0;
if(s!=a[i].name) stable=0;
}
if(right&&stable) {puts("Right");continue;}
puts( right ?"Not Stable":"Error") ;
for(int i=1;i<=n;i++)
{
cout<<a[i].name<<" "<<a[i].score<<endl;
}
}
return 0;
}
时间复杂度有说是O(n^1.5),有说是O(n^1.3),这得根据n的数量级和delta序列的取值而定。
4.归并排序 merge_sort hdu 2020
绝对值排序
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 60626 Accepted Submission(s): 29119
Problem Description
输入n(n<=100)个整数,按照绝对值从大到小排序后输出。题目保证对于每一个测试实例,所有的数的绝对值都不相等。
Input
输入数据有多组,每组占一行,每行的第一个数字为n,接着是n个整数,n=0表示输入数据的结束,不做处理。
Output
对于每个测试实例,输出排序后的结果,两个数之间用一个空格隔开。每个测试实例占一行。
Sample Input
3 3 -4 2 4 0 1 2 -3 0
Sample Output
-4 3 2 -3 2 1 0
Author
lcy
Source
Recommend
时间复杂度O(n*logn)
空间复杂度O(n)
没神马好说的
时间复杂度最好最坏都一样,是O(n*logn);
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI (4.0*atan(1.0))
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson ind<<1,le,mid
#define rson ind<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
#define ysk(x) (1<<(x))
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn= 100+20 ;
//const int maxV=200+10 ;
int n;
int a[maxn];
int T[maxn];
void merge(int le,int mid,int ri)
{
//if(le>ri) return; 这句话没必要,不可能,这种情况无外乎之后调用merge_sort时出现le==ri的情况。
int k=le,p1=le,p2=mid+1;//否则来一次mid=(le+ri)>>1;绝对有mid<le ,(也就是说++mid<=le)
while(p1<=mid&&p2<=ri)
{
if(abs(a[p1])>abs(a[p2]) ) T[k++]=a[p1++];//两边都要++
else T[k++]=a[p2++];//两边都要++
}
while(p1<=mid) T[k++]=a[p1++];
while(p2<=ri) T[k++]=a[p2++];
memcpy( a+le, T+le,(ri-le+1)*sizeof a[0] );
}
void merge_sort(int le,int ri)
{
if(le>=ri) return;//每次merge之后就a的相应区间就已经拍好了,如果le==ri直接返回,不用再排。
MID;//以我这个写法,le==ri时,如果不return,还会无限递归,导致爆栈出错。
merge_sort(le,mid);
merge_sort(mid+1,ri);
merge(le,mid,ri);
}
int main()
{
while(~scanf("%d",&n)&&n)//坑爹,掉了&&n!!!
{
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
merge_sort(1,n);
for(int i=1;i<=n;i++)
{
if(i!=1) putchar(' ');
printf("%d",a[i]);
}
putchar('\n');
}
return 0;
}
5.堆排序(不稳定的)
时间复杂度O(n*logn)
空间复杂度O(n)
hdu 3789 结果是wrong answer 但是堆排序应该是没问题的,作为复习,懒得找错了。
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI (4.0*atan(1.0))
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson ind<<1,le,mid
#define rson ind<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
#define ysk(x) (1<<(x))
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn=100010 ;
//const int maxV=12 ;
int ans[maxn][4];
int n,m;
struct A
{
int gold;
int medal;
double people;
}a[maxn];
struct Node
{
int ind;
double val;
Node(){}
Node(int ind ,double val):ind(ind),val(val){}
};
vector<Node> ve;
bool vis[maxn];
void heap_adjust(int now,int m)
{
Node t=ve[now];
for( int nex=2*now+1;nex<=m;nex=2*now+1)
{
if(nex+1<=m &&ve[nex+1].val<ve[nex].val ) nex++;
if(t.val<ve[nex].val) break;
ve[now]=ve[nex] ;now=nex;
}
ve[now]=t;
}
void heap_sort()
{
for(int i=m/2-1;i>=0;i--)
{
heap_adjust(i,m-1);
}
for(int i=m-1;i>0;i--)
{
swap(ve[0],ve[i]);
heap_adjust(0,i-1);
}
}
void getans(int pos)
{
int cnt=0;double last=-1;
int add=1;
for(int i=0;i<ve.size();i++)
{
int x=ve[i].ind;
double val=ve[i].val;
if(fabs(val-last)>eps ) cnt+=add,add=1;//这里经常出错,无论是否相等last都应该更新
else add++;
ans[x][pos]=cnt;
last=val;
}
}
bool cmp(Node x,Node y)
{
if( fabs(x.val-y.val)>eps )
{
return x.val<y.val;
}
return x.ind<y.ind;
}
/*
bool cmp2(Node x,Node y)
{
return x.val>y.val;
}*/
void work()
{
for(int pos=0;pos<=3;pos++)
{
ve.clear();
for(int i=0;i<n;i++) if(vis[i])
{
if(pos==0) ve.push_back(Node(i,a[i].gold));
else if(pos==1) ve.push_back(Node(i,a[i].medal));
else if(pos==2) ve.push_back(Node(i,a[i].gold/a[i].people));
else ve.push_back(Node(i,a[i].medal/a[i].people));
}
heap_sort();
// stable_sort(ve.begin(),ve.end(),cmp2);
getans(pos);
}
for(int i=0;i<n;i++) if(vis[i])
{
ve.clear();
for(int j=0;j<4;j++)
{
ve.push_back(Node(j+1,ans[i][j]));//排名方式,成绩,即排名
}
sort(ve.begin(),ve.end(),cmp);
printf("%d:%d\n",int(ve[0].val+0.5),ve[0].ind );
// printf("%d:%d\n",ve[0].val+0.5,ve[0].ind); //两个错误写法
// printf("%d:%d\n",(int)ve[0].val+0.5,ve[0].ind );//两个错误写法
}
putchar('\n');
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(vis,0,(n+1)*sizeof vis[0]);
for(int i=0;i<n;i++)
{
scanf("%d%d%lf",&a[i].gold,&a[i].medal,&a[i].people);
}
int x;
for(int i=0;i<m;i++)
{
scanf("%d",&x);
vis[x]=1;
}
work();
}
return 0;
}