WA30分求调

题目描述

时间限制:1s

空间限制:256MB

题意描述

离散化在许多题目中可以简化空间的分配方式,降低编程复杂度。现在你得到了一个数组 a[],你需要将其离散化得到数组 b[],满足对于任意 i,j

  • a_i=a_j ,则 b_i=b_j
  • a_i<a_j ,则 b_i<b_j

除此之外,你还需要保证,如果存在 i 使得 b_i=x>1 ,则存在 j 使得 b_j=x-1 。并且存在 k 满足 b_k\ge 1

可以证明这样的离散方式是唯一的。

输入描述

第一行一个整数 n ,表示数组长度。

第二行 n 个整数 a_i ,表示a[]数组

输出描述

一行 n 个整数 b_i ,表示b[]数组

样例

样例输入 1

5
5 10 25 10 30

样例输出 1

1 2 3 2 4

数据范围

对于所有数据, 1\le n\le10^5,1\le a_i\le10^9
子任务 1(30 分): a_i 互不相同;
子任务 2(70 分):没有特殊限制。

#include<bits/stdc++.h>
using namespace std;
int main(){
  int n,m;
  vector<int>a,c;
  map<int,int>b;
  cin>>n;
  for(int i=0;i<n;i++){
    cin>>m;
    a.push_back(m);
  }c=a;
  sort(c.begin(),c.end());
  unique(c.begin(),c.end());
  for(int i=0;i<c.size();i++)b[c[i]]=i;
  for(int i=0;i<n;i++)cout<<b[a[i]]+1<<" ";
  return 0;
}
2 个赞

@huangfeidong 我好像知道了

1 个赞

5
114 114 114 114 114

应该输出:1 1 1 1 1

你输出:5 5 5 5 5

1 个赞

有没有什么可以改进的思路

2 个赞

可以用vector去重,在用二分查找寻找位置输出即可

2 个赞

如果要用map呢?

2 个赞

二分模版如下(查找第一个为x的位置):

int l=1,r=n;
while(l<r){
   int mid=l+r>>1;
   if(a[mid]>=x) r=mid;
   else l=mid+1;
}
2 个赞

用map加数组就行了(坏了,代码来不及删了)

1 个赞

突然意识到这一课的课后作业多了两道题

2 个赞

2 个赞

不是你哪来的经典贪心

2 个赞

我9月7日就开始上了啊

2 个赞

脑子短路了,不知道怎么做

2 个赞

@huangfeidong

拜托把解决方案给这个帖:
用c数组把a数组存一下,然后排序(你应该都会)
然后用i,j,for循环(i枚举下标,j枚举这个数离散化成j)
比如:
5
a=114 514 1919 8 10
c=114 514 1919 8 10
排序后:c=8 10 114 514 1919
如果这个数没出现过就把他赋值成j,因为c是有序的。赋值完后j要++ 
i:1 2 3 4 5
b:b[8]=1,b[10]=2,b[114]=3,b[514]=4,b[1919]=5(括号里的数就是c)
j:1 2 3 4 5

后面就cout<<b[a[i]]就行了
1 个赞

蟹蟹

2 个赞

@huangfeidong 解决方案给那个帖

1 个赞

哪个?

2 个赞

这个指的就是这个

3 个赞

本来就是对的

他在提醒你要给解决方案

3 个赞