zjnu1725 COCI (类似二维树状数组模拟)
2016-03-15 19:16
459 查看
Description
The 3rd round of COCI is already here! In order to bet on predict the scores, we have assumed the following:
If contestant A scored strictly more points than contestant B in each of the first two rounds, then in the
third round A will score at least an equal amount of points as B.
Of course, in each round (including this one, the 3rd one) it is possible to score from 0 to 650 points. On the
total ranking list, contestants are sorted descending according to the sum of points from all three rounds.
The contestants with an equal sum share the same place and the next contestant gets the realistic following place.
For example, contestants with sums equal to 1000, 1000, 900, 900 and 800 points win places 1., 1., 3., 3. and 5.,
respectively.
For each of the N contestants, we know the number of points scored in the first and second round. Given the
aforementioned assumption, determine the highest and lowest place each contestant can get on the total ranking
list after three rounds of COCI.
Input
The first line of input contains an integer N (1 <= N <= 500000), the number of contestants.
Each of the following N lines contains two integers from the interval [0; 650]: the number of points each contestant
won in the first and second round.
Output
For each contestant, in the order given in the input, output two integers per line: the required highest and lowest
place they can get on the total ranking list.
Sample Input
5
250 180
250 132
220 123
132 194
220 105
10
650 550
550 554
560 512
610 460
610 456
650 392
580 436
650 366
520 456
490 456
Sample Output
1 3
1 3
3 5
1 5
3 5
1 4
1 8
2 8
2 7
2 9
1 10
4 10
1 10
5 10
5 10
题意:n个人进行决斗,共有三场比赛,前两场比赛的成绩已经知道了,第三场的成绩未知,已知如果A前两场比赛每一场比赛成绩都严格高于B,那么A的第三场成绩一定大于等于B,最后的结果按三场总成绩从高到低排序,问每一个人最好的名次和最差的名词分别可能为多少。
思路:先考虑一个人A最好的情况,那么A得到的分数为650分,那么之前两场严格高于她的人最后一定也高于她,如果B之前一门小于等于她,另一门高于她,这种情况最后也不会比她高,因为可以另B的第三门成绩为0,那么A的成绩一定是大于等于B的(等于的情况有两种,一种是第二门成绩为0,但是B的第二门成绩为650,第一门成绩两者相同,另一种是第一种第二种反一下),又因为两者成绩相等自己不会退后名词,所以可以不用管。再考虑A最坏的情况,我们考虑比A考的差的人,这里和之前一样,只是要考虑(0,0,a[i]-1,b[i]-1)的总数,这里还要考虑和她成绩相同的情况,就是A的a[i]或者b[i]=650,要减去这些,然后用n减去比她考的差的人数就是答案了。
注意:这题不能用树状数组,因为会超时,又因为点的坐标大小都很小,所以可以用s[i][j]表示x小于等于i,y小于等于j的坐标总数。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define NN 500050
#define MM 650
int a[NN],b[NN];
int k[MM+10][MM+10],s[MM+10][MM+10];
int solve(int p,int q,int P,int Q)
{
int i,j;
if(P<0 || Q<0)return 0;
int sum=s[P][Q];
if(p>0){
sum-=s[p-1][Q];
}
if(q>0){
sum-=s[P][q-1];
}
if(p>0 && q>0){
sum+=s[p-1][q-1];
}
return sum;
}
int main()
{
int n,m,i,j,c,d;
while(scanf("%d",&n)!=EOF)
{
memset(k,0,sizeof(k));
memset(s,0,sizeof(s));
for(i=1;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);
k[a[i] ][b[i] ]++;
}
for(i=0;i<=MM;i++){
for(j=0;j<=MM;j++){
s[i][j]=k[i][j];
if(i>0){
s[i][j]+=s[i-1][j];
}
if(j>0){
s[i][j]+=s[i][j-1];
}
if(i>0 && j>0){
s[i][j]-=s[i-1][j-1];
}
}
}
for(i=1;i<=n;i++){
printf("%d ",solve(a[i]+1,b[i]+1,MM,MM)+1 );
printf("%d\n",n-solve(0,0,a[i]-1,b[i]-1)-k[a[i] ][0]*(b[i]==MM)-k[0][b[i] ]*(a[i]==MM) );
}
}
return 0;
}
The 3rd round of COCI is already here! In order to bet on predict the scores, we have assumed the following:
If contestant A scored strictly more points than contestant B in each of the first two rounds, then in the
third round A will score at least an equal amount of points as B.
Of course, in each round (including this one, the 3rd one) it is possible to score from 0 to 650 points. On the
total ranking list, contestants are sorted descending according to the sum of points from all three rounds.
The contestants with an equal sum share the same place and the next contestant gets the realistic following place.
For example, contestants with sums equal to 1000, 1000, 900, 900 and 800 points win places 1., 1., 3., 3. and 5.,
respectively.
For each of the N contestants, we know the number of points scored in the first and second round. Given the
aforementioned assumption, determine the highest and lowest place each contestant can get on the total ranking
list after three rounds of COCI.
Input
The first line of input contains an integer N (1 <= N <= 500000), the number of contestants.
Each of the following N lines contains two integers from the interval [0; 650]: the number of points each contestant
won in the first and second round.
Output
For each contestant, in the order given in the input, output two integers per line: the required highest and lowest
place they can get on the total ranking list.
Sample Input
5
250 180
250 132
220 123
132 194
220 105
10
650 550
550 554
560 512
610 460
610 456
650 392
580 436
650 366
520 456
490 456
Sample Output
1 3
1 3
3 5
1 5
3 5
1 4
1 8
2 8
2 7
2 9
1 10
4 10
1 10
5 10
5 10
题意:n个人进行决斗,共有三场比赛,前两场比赛的成绩已经知道了,第三场的成绩未知,已知如果A前两场比赛每一场比赛成绩都严格高于B,那么A的第三场成绩一定大于等于B,最后的结果按三场总成绩从高到低排序,问每一个人最好的名次和最差的名词分别可能为多少。
思路:先考虑一个人A最好的情况,那么A得到的分数为650分,那么之前两场严格高于她的人最后一定也高于她,如果B之前一门小于等于她,另一门高于她,这种情况最后也不会比她高,因为可以另B的第三门成绩为0,那么A的成绩一定是大于等于B的(等于的情况有两种,一种是第二门成绩为0,但是B的第二门成绩为650,第一门成绩两者相同,另一种是第一种第二种反一下),又因为两者成绩相等自己不会退后名词,所以可以不用管。再考虑A最坏的情况,我们考虑比A考的差的人,这里和之前一样,只是要考虑(0,0,a[i]-1,b[i]-1)的总数,这里还要考虑和她成绩相同的情况,就是A的a[i]或者b[i]=650,要减去这些,然后用n减去比她考的差的人数就是答案了。
注意:这题不能用树状数组,因为会超时,又因为点的坐标大小都很小,所以可以用s[i][j]表示x小于等于i,y小于等于j的坐标总数。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define NN 500050
#define MM 650
int a[NN],b[NN];
int k[MM+10][MM+10],s[MM+10][MM+10];
int solve(int p,int q,int P,int Q)
{
int i,j;
if(P<0 || Q<0)return 0;
int sum=s[P][Q];
if(p>0){
sum-=s[p-1][Q];
}
if(q>0){
sum-=s[P][q-1];
}
if(p>0 && q>0){
sum+=s[p-1][q-1];
}
return sum;
}
int main()
{
int n,m,i,j,c,d;
while(scanf("%d",&n)!=EOF)
{
memset(k,0,sizeof(k));
memset(s,0,sizeof(s));
for(i=1;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);
k[a[i] ][b[i] ]++;
}
for(i=0;i<=MM;i++){
for(j=0;j<=MM;j++){
s[i][j]=k[i][j];
if(i>0){
s[i][j]+=s[i-1][j];
}
if(j>0){
s[i][j]+=s[i][j-1];
}
if(i>0 && j>0){
s[i][j]-=s[i-1][j-1];
}
}
}
for(i=1;i<=n;i++){
printf("%d ",solve(a[i]+1,b[i]+1,MM,MM)+1 );
printf("%d\n",n-solve(0,0,a[i]-1,b[i]-1)-k[a[i] ][0]*(b[i]==MM)-k[0][b[i] ]*(a[i]==MM) );
}
}
return 0;
}
相关文章推荐
- shell入门指南
- 第二周项目二就拿胖子说事
- Add user to sudoers - 润物无声 - 博客频道 - CSDN.NET
- 简明python教程 --C++程序员的视角(二):函数及作用域
- LeetCode 82. Remove Duplicates from Sorted List II
- BZOJ1570Blue Mary的旅行
- 红包分配算法(年后写的)
- Apache Stratos探究:4.1.x Application Resource Definition(应用程序资源定义)
- 版本管理工具 - SVN
- 阅后即焚的产品价值
- Bloom Filter
- HDU 1030.Delta-wave【找规律、最短路】【3月15】
- 解决Myeclipse开发jsp卡的问题
- Android中振动器(Vibrator)的使用
- 简明python教程 --C++程序员的视角(一):数值类型、字符串、运算符和控制流
- PyCharm快捷键
- 160315
- PostgreSQL pg_hba.conf 文件解析以及忘记密码的处理方法
- Android中的Apk的加固(加壳)原理解析和实现(转)
- 机器学习 (笔记)牛顿方法