POJ 2352 Stars
一、题目大意
给出个点坐标, 按照升序的顺序, 若相同, 则按照升序的顺序. (不用我们自己排序,是由小到大的顺序给出的坐标)
一个点坐标小于另一个点坐标的含义是, 横纵坐标都不大于另一个点坐标(保证没有两个点坐标完全相同).
对于给出的个点中, 定义该点等级为: 小于该点的所有坐标之和. (左下角星星的个数)
问: 对于的所有等级, 输出有多少个点坐标为该等级.
二、解题思路
乍一看好像是二维树状数组,但是本题降低了难度,对于输入是按照:的升序给出坐标,如果相同,则按照的升序给出。
注:不是应该声明个结构体,然后让我们排序后再捋着来计算的吗?良心发现吗?还是有什么新的企图??
那么输入第颗星星的坐标时,小于等于,小于等于,即左下角的星星已经全部出现了,且按照升序给出,因此,可以忽略坐标,只需要找到小于等于的星星数量就是星星的级数。
设定数组,表示坐标为的星星个数。
找小于等于的星星,即找前缀和。
注:题目下标从开始,而树状数组不能有下标为的情况,所以整体右移动一位。
二、实现代码
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 32010;
int cnt[N];
// 树状数组模板
#define lowbit(x) (x & -x)
typedef long long LL;
int c[N];
void add(int x, int v) {
while (x < N) c[x] += v, x += lowbit(x);
}
LL sum(int x) {
LL res = 0;
while (x) res += c[x], x -= lowbit(x);
return res;
}
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
int x, y;
scanf("%d %d", &x, &y); // 这里的y没有用到,想想也是,因为是扫描线是从下向上的,与y的具体值无关
x++; // 树状数组存储从1开始, 所有x映射都+1。
add(x, 1);
// 查询在x之前有多少个数字,也就是有多少个星星个数
cnt[sum(x)]++; // 找到了一个左下角有5个星星的,那么5这个桶计数++,这是题意要求的
}
// 输出所有等级星星的个数
for (int i = 1; i <= n; i++) printf("%d\n", cnt[i]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2020-05-04 Windows下使用SSH密钥实现免密登陆Linux服务器
2013-05-04 我们项目中需要准备的技术
2013-05-04 window 2003 实现多用户远程登录
2013-05-04 XSS的知识普及和预防办法
2013-05-04 免积分下载CSDN软件和新浪资料