牛客练习赛50 B tokitsukaze and Hash Table

题目::
链接:https://ac.nowcoder.com/acm/contest/1080/B

                 tokitsukaze有n个数,需要按顺序把他们插入哈希表中,哈希表的位置为0到n-1。

                 插入的规则是:
                 刚开始哈希表是空的。
                 对于一个数x,在哈希表中,如果(x mod n)的位置是空的,就把x放在(x mod n)的位置上。如果不是空的,就从(x mod n)往右开始找到第一个空的位置插入。若一直到n-1都不是空                    的,就从位置0开始继续往右找第一个空的位置插入。

                 因为哈希表总共有n个空位,需要插入n个数,所以每个数都能被插入。

                现在tokitsukaze想知道把这n个数按顺序插入哈希表后,哈希表中的每个位置分别对应的是哪个数。

     输入::

              第一行包含一个正整数n(1≤n≤10^6)。
              第二行包含n个非负整数x(0≤x≤10^9),这些数按从左到右的顺序依次插入哈希表。

    输出::

      输出一行,n个数,第i个数表示哈希表中位置为i所对应的数。(0≤i≤n-1)

    样例1::

      4
      1 2 6 5

    样例2::

      4
      3 0 7 11

分析::
普通思路走一次搜一次必定TLE;那我们可以优化一下二分来写,这就很好的想到了set 容器;
首先预处理将0~n-1插入进set中,对于输入的数据做处理,利用lower_bound函数可以快速找到第一个空位置,并将它删除;当返回的是end()是则需更改成s.begin();并且删除;
这里返回的迭代器所代表的值即是安放的位置,可以开个数组来存储;
详细见代码::
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll MOD=998244353;
 5 const int maxn=1e6+10;
 6 int ma[maxn];
 7 set<int>s;
 8 int main()
 9 {
10     s.clear();
11     int n;
12     scanf("%d",&n);
13     for(int i=0;i<n;i++){
14         s.insert(i);
15     }
16     for(int i=1;i<=n;i++){
17         int x,k;
18         scanf("%d",&x);
19         int ans=x;
20         x%=n;
21         set<int>::iterator it;
22         it=s.lower_bound(x);
23         if(it!=s.end()){
24             k=*it;
25             s.erase(it);
26         }
27         else{
28             it=s.begin();
29             k=*it;
30             s.erase(it);
31         }
32         ma[k]=ans;
33     }
34     for(int i=0;i<n;i++){
35         if(i==0){
36             printf("%d",ma[i]);
37         }
38         else{
39             printf(" %d",ma[i]);
40         }
41     }
42     return 0;
43 }

           本人此题还有解法

           类似并查集 (也不能这样说,-_-  )

          分析::

          首先也是预处理记录 0~n-1,然后通过找祖宗找到空位置

        

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll MOD=998244353;
 5 const int maxn=1e6+10;
 6 int ma[maxn];
 7 int f[maxn];
 8 int getfather(int x)
 9 {
10     return x==f[x]?x:f[x]=getfather(f[x]);
11 }
12 int main()
13 {
14     int n;
15     scanf("%d",&n);
16     for(int i=0;i<n;i++){
17         f[i]=i;
18     }
19     for(int i=1;i<=n;i++){
20         int x,y;
21         scanf("%d",&x);
22         y=x;
23         x=getfather(x%n);
24         ma[x]=y;
25         f[x]=(x+1)%n;//更改已被占的位置并指向后面第一个空位置
26     }
27     for(int i=0;i<n;i++){
28         if(i==0){
29             printf("%d",ma[i]);
30         }
31         else{
32             printf(" %d",ma[i]);
33         }
34     }
35     return 0;
36 }

 

posted @ 2019-08-25 13:52  sj-_-js  阅读(189)  评论(0编辑  收藏  举报