题意:
如图,等级为0的点有1,等级为1得点有4,2 等级为2的点有3,等级为3的点有5-------即即左下角的点的个数
现给你一些点(x,y),输入顺序按y升序,y相等时按x升序排列
请分别输出等级0---n-1的点的个数
分析:
暴力超时TEL,用g++提交也超时
#include<iostream> #include<cstring> #include<cstdio> #include "cstring" using namespace std; int a[15005]; int c[15005]; int main() { int n; while(scanf("%d",&n)!=EOF) { int x,cnt=0; memset(c,0,sizeof(c)); for(int i=0;i<n;i++) { scanf("%d%d",&a[i],&x); for(int j=0;j<i;j++) if(a[j]<=a[i]) cnt++;///属于哪个水平? c[cnt]++; cnt=0; } for(int i=0;i<n;i++) { printf("%d ",c[i]); } } return 0; }
再分析
只统计之前小于等于x的点的个数,即可确定等级
统计个数,需用到求和,用树状数组
#include "cstdio" #include "cstring" #include "iostream" using namespace std; int c[32000+5];///下标代表x值,值代表个数 int a[32000+5];///下标代等级,值代表个数 int lowbit(int x) { return x&(-x); } void update(int i,int plus) { while(i<=32005) { c[i]+=plus; i+=lowbit(i); } } int getSum(int x) { int s=0; while(x>0) { s+=c[x]; x-=lowbit(x); } return s; } int main() { int n; while(scanf("%d",&n)!=EOF)///确定一个等级,统计小于x的个数 { int x,y; memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); for(int i=0;i<n;i++) { scanf("%d%d",&x,&y); a[getSum(x+1)]++;///等级确定=统计c(1->x)个数 update(x+1,1);///c 对应x +1 } for(int i=0;i<n;i++) { printf("%d ",a[i]); } } return 0; }