poj 2352 Stars

题意:

在一个平面直角坐标系中,定义一个星星的level为横坐标小于等于且纵坐标小于等于它的坐标的星星的个数。

给出若干个星星的坐标,问level为0-n-1的星星分别有多少。

思路:

将星星按照横坐标递增排序,如果横坐标相同,按照纵坐标递增排序。

然后分别找横坐标和纵坐标的前缀和,小的那个就是这个星星的level。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 35000;
 6 int cx[N],cy[N];
 7 int mx,my;
 8 struct node
 9 {
10     int x,y;
11 } a[15005];
12 int ans[15005];
13 bool cmp(node xx,node yy)
14 {
15     if (xx.x == yy.x) return xx.y < yy.y;
16     return xx.x < yy.x;
17 }
18 int lowbit(int x)
19 {
20     return x&(-x);
21 }
22 void addx(int x,int y)
23 {
24     for (int i = x;i <= mx;i+=lowbit(i)) cx[i] += y;
25 }
26 void addy(int x,int y)
27 {
28     for (int i = x;i <= my;i += lowbit(i)) cy[i] += y;
29 }
30 int getsumx(int x)
31 {
32     int ans = 0;
33     for (int i = x;i > 0;i -= lowbit(i)) ans += cx[i];
34     return ans;
35 }
36 int getsumy(int x)
37 {
38     int ans = 0;
39     for (int i = x;i > 0;i -= lowbit(i)) ans += cy[i];
40     return ans;
41 }
42 int main()
43 {
44     int n;
45     while (scanf("%d",&n) != EOF)
46     {
47         mx = 0,my = 0;
48         memset(ans,0,sizeof(ans));
49         memset(cx,0,sizeof(cx));
50         memset(cy,0,sizeof(cy));
51         for (int i = 0;i < n;i++)
52         {
53             int x,y;
54             scanf("%d%d",&x,&y);
55             x++,y++;
56             a[i].x = x,a[i].y = y;
57             mx = max(x,mx);
58             my = max(y,my);
59         }
60         sort(a,a+n,cmp);
61         for (int i = 0;i < n;i++)
62         {
63             int tx = getsumx(a[i].x);
64             int ty = getsumy(a[i].y);
65             ans[min(tx,ty)]++;
66             addx(a[i].x,1);
67             addy(a[i].y,1);
68         }
69         for (int i = 0;i < n;i++) printf("%d\n",ans[i]);
70     }
71     return 0;
72 }

 

posted @ 2018-05-21 21:07  qrfkickit  阅读(115)  评论(0编辑  收藏  举报