http://acm.sgu.ru/problem.php?contest=0&problem=171
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=22553
Sarov zones
Time Limit: 500MS Memory Limit: 4096KB 64bit IO Format: %I64d & %I64u
[Submit] [Go Back] [Status]
Description
It is known that to participate the All-Russian Mathematic Olympiad one should do one of other olympiads enough good. These olympiads are called "zone olympiads" and the region from which people participate the same zone olympiad is called "zone". Sarov city of Nizhny Novgorod district is situated near the boundary of zones, so every year school students of Sarov participate several zones.
This year K zones invited students from Sarov to participate their olympiads. i-th zone invited N[i] students, so N=N[1]+N[2]+...+N[K] totally students were invited. After the Sarov city olympiad, N students were selected, so now the olympiad authorities of Sarov have to decide, which students will participate which zone olympiad. Each student is characterized by his olympiad level and each zone is characterized by its zone level. If a student with olympiad level P participates zone with zone level Q, he will be invited to All-Russian olympiad if and only if P>Q.
Every student is also characterized by his "weight". The Sarov olympiad authorities want, that the All-Russian Olympiad will be participated by students with maximal summary weight. You are to help them. Write a program which will divide the students between zones. Keep in mind that exactly N[i] students can go to i-th zone.
Input
On the first line of input there is an only integer K (1<=K<=100). On the second line there are K integers N[1], N[2], ... ,N[K] (0<=N[i]<=16000). On the third line there are K more integers Q[1], Q[2], ... ,Q[K] --- the zone levels of the zones. On the fourth line there are N integers P[1], P[2], ... P[N] --- olympiad levels of the students. (0<=Q[i]<=1000000, 0<=P[i]<=1000000). On the last (and fifth) line there are N integers w[1], w[2], ... w[k] --- the "weights" of students. 0<=w[i]<=100000. It is also guaranteed that 0<=N<=16000.
Output
Output only N integers --- Z[1], Z[2], ... Z[N] --- the numbers of zones which should be participated by students 1, 2, ... N.
Sample Input
Input
2
1 1
4 1
2 3
2 1
Output
2 1
[Submit] [Go Back] [Status]
解析:
题意:
有K个区域,给出每个区域招生有固定的招生数以及录取分数线,同时也给所有学生的分数以及体重
当学生分数超过录取分数线是一定会被录取,但是每个区域要求招满学生,且使得总招生体重之和尽量大
思路:
类似于高考填志愿,以考生的角度思考问题,使得学生尽量报考好的学校,所以是学生选学校
1.现将区域的录取分数按照从大到小,考生体重从大到小排序
2.进行第一轮选择,以分数作为选择条件
3.第二轮选择,使的地区招满学生
PS:这一题报错了n次,最终发现实际上是输出出现了问题。当K=0时是没有结果输出的。
早知如此就应该多测几组特殊数据的。。。。。。。
Memory Time Language Length Submit Time
1075 KB 31 ms Visual Studio C++ 2010 1246 B 2013-07-22 14:50:09
*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int maxn=16000+5;
struct zone
{
int id;
int num;
int level;
}z[105];
struct student
{
int id;
int level;
int w;
}s[maxn];
int N[maxn];
int n,k;
bool cmp1( zone s1, zone s2)
{
return s1.level>s2.level;
}
bool cmp2(student s1, student s2)
{
return s1.w>s2.w;
}
void solve()
{ int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<k;j++)//按分数选
if(s[i].level>z[j].level&&z[j].num>0)
{N[s[i].id]=z[j].id;//s[i].id选择了z[j].id地区
z[j].num--;
break;
}
}
for(i=0;i<n;i++)if(N[s[i].id]==0)
{
for(j=0;j<k;j++)//按照体重选择
if(z[j].num>0)
{N[s[i].id]=z[j].id;//s[i].id选择了z[j].id地区
z[j].num--;
break;
}
}
for(i=1;i<=n;i++)
{printf("%d",N[i]);
if(i!=n)
printf(" ");
else
printf("\n");
}
}
int main()
{ int i,j;
while(scanf("%d",&k)!=EOF)
{ n=0;
for(i=0;i<k;i++)
{
scanf("%d",&z[i].num);
n+=z[i].num;
z[i].id=i+1;
}
for(i=0;i<k;i++)
{scanf("%d",&z[i].level);
}
for(j=0;j<n;j++)
{
scanf("%d",&s[j].level);
s[j].id=j+1;
}
for(j=0;j<n;j++)
{scanf("%d",&s[j].w);
}
sort(s,s+n,cmp2);
sort(z,z+k,cmp1);
memset(N,0,sizeof(N));
solve();
}
return 0;
}