题目描述

Lemon最近迷上了一款坦克对战游戏。在这款游戏中,Lemon需要驾驶一辆坦克与敌军对战。

坦克有很多不同的武器,每种武器有各自的特点,而Lemon所要做的就是合适地发射这些武器,对敌军造成最大的伤害。具体来说,每个武器都有两个参数:攻击力D和攻击半径R。为了简化题意,我们保证所有武器的攻击力D均不相同,所有武器的攻击半径R也均不相同。

Lemon决定对这些武器的性能进行评价。当然,评价不能只看攻击力D,也不能只看攻击半径R。Lemon觉得一件武器A优于另一件武器B,当且仅当A的攻击力大于B的攻击力且A的攻击半径大于B的攻击半径。

接下来,Lemon想要对武器进行分组,Lemon按照以下方式分组:

首先,我们定义f(A,S)为真当且仅当在武器集合S中的任何武器都不比武器A性能更优秀。

(1)令i=0;

(2)令i=i+1;令S=还没被分组的武器集合;

(3)对于每一件S中的武器A,如果f(A,S)为真,则将武器A标记为第i组(注意S在这个过程中始终保持不变);

(4)如果所有武器均被分组则结束,否则转2。

给定N个武器的D和R,你的任务是按照Lemon的规则对这些武器进行分组。

输入输出格式

输入格式

输入文件第一行包含一个正整数N,表示武器的个数。

接下来N行,每行两个正整数D、R,描述一件武器的攻击力和攻击半径。保证所有的D两两不同,所有的R两两不同。

输出格式

输出文件包含N行,每行一个正整数,第i行的数表示第i件武器被分在了哪一组。

样例

INPUT

5

1 4

2 2

3 3

4 1

5 5

OUTPUT

2

3

2

2

1

HINT

首先我们发现武器5比武器1性能更优,所以武器1不在第1组。同理武器2、3、4也不在第1组。

但没有武器比武器5性能更优,因此武器5在第1组。

接下来还剩武器1、2、3、4没被分组。我们发现这些武器中没有武器比武器1更优,于是武器1在第2组,同理武器3、4也在第2组。

接下来只剩武器2了,武器2在第3组。

此时所有武器均被分组,过程结束。

对于20%的数据,N≤100;对于40%的数据,N≤3000;对于100%的数据,N≤100000;1≤R、D≤10^9。

SOLUTION

贪心

\(O(n^2)\)的做法好像不会,因为觉得写的很麻烦,索性放弃。其实写对贪心有一部分就是歪打正着qwq

把每个武器的两个参数\(d,r\),分别为第一关键字和第二关键字排序,得到了以d为主关键字降序的新序列。我们已知,对于第\(i,j\)个武器只有当①\(d_i>d_j\)且②\(r_i>r_j\)时编号为\(i\)的武器才能完全压制编号为\(j\)的武器,这时就不能把\(i,j\)分为一组。

所以当我们把所有武器以\(d\)为主关键字降序排序时已经保证了①条件的成立,所以若要使后面的武器\(i\)能够不被第\(j\)组完全压制,只有满足\(r_i>R_{j}\)时才能成立,若不能成立,我们就开一个新的组,这时候可以看出我们最后的\(R\)数组是满足单调性的,于是就可以二分。

于是我们的\(O(nlogn)\)的算法就出来了。

\(P.S.\)下面是我考场上的代码,其中\(lft\)数组是赘余的,而且变量命名也很奇怪,将就着看吧qwq。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define Min(a,b) ((a<b)?a:b)
#define Max(a,b) ((a>b)?a:b)
inline int read(){
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-48;ch=getchar();}
return x*f;}
const int N=101000;
int n,blg[N],lft[N],rgt[N],L,R,sch;
struct NODE{int d,r,u;}nd[N];
bool cmp(NODE x,NODE y){if (x.d==y.d) return x.r>y.r;return x.d>y.d;}
inline void bsh(int l,int r){
if (l==r) {sch=l;return;}
if (l+1==r) {if ((L>=lft[l])||(R>=rgt[l])) sch=l;else sch=r;return;}
int mid=(l+r)>>1;
if ((L>=lft[mid])||(R>=rgt[mid])) bsh(l,mid);else bsh(mid+1,r);}
int main(){
freopen("tank.in","r",stdin);
freopen("tank.out","w",stdout);
int i,j;
n=read();for (i=1;i<=n;++i) {nd[i].d=read();nd[i].r=read();nd[i].u=i;}
sort(nd+1,nd+1+n,cmp);memset(blg,0,sizeof(blg));
memset(lft,0,sizeof(lft));memset(rgt,0,sizeof(rgt));
int cnt=0;
for (i=1;i<=n;++i){
L=nd[i].d,R=nd[i].r;
//printf("*%d *%d:",L,R);
bsh(1,cnt+1);if (sch==(cnt+1)) cnt++;
lft[sch]=Max(lft[sch],L);rgt[sch]=Max(rgt[sch],R);
blg[nd[i].u]=sch;
//printf("cnt:%d sch:%d\n",cnt,sch);
}
for (i=1;i<=n;++i) printf("%d\n",blg[i]);
return 0;
}

JXJJOI2018_T2_tank的更多相关文章

随机推荐

  1. 爬虫—GEETEST滑动验证码识别

    一.准备工作 本次使用Selenium,浏览器为Chrome,并配置好ChromDriver 二.分析 1.模拟点击验证按钮:可以直接使用Selenium完成.    2.识别滑块的缺口位置:先观察图 ...

  2. win10环境下pyinstaller打包pytorch遇到的问题及解决方案

    pytorch-python源码生成windows的应用程序(.exe),报错OSError: could not get source code Failed to execute script h ...

  3. java 里没有友元函数怎么办

    我希望一个service可以访问某个对象中的私有对象,但是不希望这个私有对象暴露给其它的service. public xxxServiceImpl{ public void do(){ xxxent ...

  4. 35)类和结构体类比---this

    那么,为啥  Test a(10)  , Test  b(20)   然后  我a.getI()  取到的是10,而不是20     就能将那个  10  给  a  对象的  m1    是因为有 ...

  5. Android 自定义dialog类

    首先定制style样式 styles.xml 加入自定义样式 <style name="CustomLoadingDialog"> <item name=&quo ...

  6. 统计一个字符串中"java"出现的次数

    public class CountJava{ public static void main(String[] args){ String str = "dnajjavaNISLjavaE ...

  7. python,pandas, DataFrame数据获取方式

    一.创建DataFrame df=pd.DataFrame(np.arange(,).reshape(,)) my_col=dict(zip(range(),['A','B','C'])) df.re ...

  8. idea整合mybatis逆向工程

    --pom.xml添加插件 <build> <finalName>hnapi</finalName> <plugins> <plugin> ...

  9. FIT AP和FAT AP的区别

    1.Fat模式是传统的WLAN组网方案,无线AP本身承担了认证终结.漫游切换.动态密钥产生等复杂功能,相对来说AP的功能较重,因此称为Fat  AP. 2.Fit模式是新兴的一种WLAN组网模式,其相 ...

  10. PAT甲级——1006 Sign In and Sign Out

    PATA1006 Sign In and Sign Out At the beginning of every day, the first person who signs in the compu ...