题目:http://acm.hdu.edu.cn/showproblem.php?pid=1541
题目大意:平面直角坐标系上有很多星星,现在计算每个星星的level
星星的level就是比当前星星坐标小的星星的总个数。例如当前星星的坐标是(x,y)
那么level就是计算从左下角从(0,0)开始到以(x,y)为右上角的矩形中,星星的总个数
输出的是从从0到N-1个level级别每个级别中星星的个数。
(初看这一题,直角坐标系。于是很自然而然的想到了二维树状数组。然后再一个anw[level]++
再循环输出anw[]就ok了。
然后就兴致勃勃的开始码二维数组的代码,保存编译。!!!编译错误,数组开的太大编译不通过,
题目是0<=x,y<=32000 二维数组tree超了,再看题目一共只给了最多15000个星星,(刚好tree[15005][15005]
能编译通过)于是又很自然而然的想到了离散化。
二维坐标系点的离散化用了一点时间,还好还是码完代码了。然后测了几组数据去提交。
!!!超内存 !!尼玛,都离散了还超内存。果断不淡定了。看看statistic,第一面全部都是几百kb就通过了
让我这爆内存到6w+的情何以堪。难道这题这么水么,我可是用了二维数组加离散化的啊!(--还不死心中)
再想了想别人通过的耗时,内存。恩!这题肯定是水题。然后又仔细了看看题目。为什么题目中强调的提示了
给定的星星坐标Y是排序好的呢? ...... 我操!(接下就是我要羞愧而死的时间了.....)
)
正题:
题目很水,输入的数据是按照Y从小到大排序的,即使Y相等也是按照X从小到大排序的,
所以完全可以不用考虑Y坐标的存在性。只需考虑星星的X就行了。而且还是可以插入一个
就计算当前星星的level,因为所有已经插入星星的Y一定不比当前星星的Y大。只需要
计算比当前星星X小的星星的个数,就是当前插入星星的level。(星星的level不包括自己)
#include<stdio.h>
#include<string.h>
#define MAX 32005
int tree[MAX],anw[MAX],maxVal;
int lowbit(int x){return x&-x;}
void update(int x,int num){
while(x<=MAX){//每次都按照最大的来
tree[x]+=num;
x+=lowbit(x);
}
}
int getSum(int x){
int sum=0;
while(x>0){
sum+=tree[x];
x-=lowbit(x);
}
return sum;
}
int main(){
int i,x,y,sum;
while(scanf("%d",&maxVal)!=EOF){
memset(tree,0,sizeof(tree));
memset(anw,0,sizeof(anw));
for(i=1;i<=maxVal;i++){
scanf("%d%d",&x,&y);
x=x+1;//题目中x>=0,我们的tree都是从1开始,所以每个X都给提高1
update(x,1);
anw[getSum(x)-1]++;//星星的level不包括自己
}
for(i=0;i<maxVal;i++){
printf("%d\n",anw[i]);
}
}
}
ps:这题一共就4个人超内存了- -,我是其中之一(╮(╯▽╰)╭)