zoukankan      html  css  js  c++  java
  • 今天刷 堆

    2879 堆的判断

    时间限制: 1 s    空间限制: 32000 KB    题目等级 : 黄金 Gold
    题目描述 Description

    堆是一种常用的数据结构。二叉堆是一个特殊的二叉树,他的父亲节点比两个儿子节点要大,且他的左右子树也是二叉堆。现在输入一颗树(用二叉树的数组表示,即a[i]的左儿子与右儿子分别为a[2i],a[2i+1]),要求判断他是否是一个堆。

    输入描述 Input Description

    一个整数N,表示结点数。

    第二行N个整数,表示每个结点代表的数字

    输出描述 Output Description

    如果是,输出‘Yes’

    否则输出‘No’

    样例输入 Sample Input

    5

    1 2 3 4 5

    样例输出 Sample Output

    No

    数据范围及提示 Data Size & Hint

    1<N<100

    数字在2^31以内

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 int a[110],n;
     6 int main()
     7 {
     8     scanf("%d",&n);
     9     for(int i=1;i<=n;i++)
    10       scanf("%d",&a[i]);
    11     for(int i=1;i<=n;i++)
    12     {
    13         if(i*2<=n){
    14             if(a[i*2]>=a[i]){
    15                 printf("No
    ");return 0;
    16             }
    17         }
    18         if(i*2+1<=n){
    19             if(a[i*2+1]>=a[i]){
    20                 printf("No
    ");return 0;
    21             }
    22         }
    23     }
    24     printf("Yes
    ");
    25     return 0;
    26 }

    3110 二叉堆练习3

    时间限制: 3 s    空间限制: 128000 KB    题目等级 : 黄金 Gold

    题目描述 Description

    给定N(N≤500,000)和N个整数(较有序),将其排序后输出。

    输入描述 Input Description

    N和N个整数

    输出描述 Output Description

    N个整数(升序)

    样例输入 Sample Input

    5

    12 11 10 8 9

    样例输出 Sample Output

    8 9 10 11 12

    数据范围及提示 Data Size & Hint

    对于33%的数据 N≤10000

    对于另外33%的数据 N≤100,000  0≤每个数≤1000

    对于100%的数据 N≤500,000  0≤每个数≤2*10^9

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 int n,t,a;
     5 int heap[500010];
     6 void heap_up(int now){
     7     if(now<=1) return;
     8     int top=now/2;
     9     if(heap[now]<heap[top])
    10      {
    11          swap(heap[now],heap[top]);
    12          heap_up(top);
    13      }
    14 }
    15 void heap_down(int now){
    16     if(now>n) return;
    17     int lc,rc,next=now;
    18     bool blc,brc;
    19     if((now*2)<=n) blc=true,lc=heap[now*2];
    20     else blc=false;
    21     if((now*2| 1)<=n) brc=true,rc=heap[now*2| 1];
    22     else brc=false;
    23     if(blc){
    24         if(heap[next]>lc)
    25           next=now<<1;
    26     }
    27     if(brc){
    28         if(heap[next]>rc)
    29           next=now << 1 | 1;
    30     }
    31     if(next!=now){
    32         swap(heap[next],heap[now]);
    33         heap_down(next);
    34     }
    35 }
    36 void heap_pop(){
    37     heap[1]=heap[n];
    38     n--;
    39     heap_down(1);
    40 }
    41 void make_heap(int x){
    42     t++;
    43     heap[t]=x;
    44     heap_up(t);
    45 }
    46 int main()
    47 {
    48     scanf("%d",&n);
    49     int m=n;
    50     for(int i=1;i<=n;i++)
    51     {
    52         scanf("%d",&a);
    53         make_heap(a);
    54     }
    55     for(int i=1;i<=m;i++)
    56     {
    57         printf("%d ",heap[1]);
    58         heap_pop();
    59     }
    60     return 0;
    61 }// 手写堆
     1 // make_heap
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 unsigned long long a[1000000+20];
     5 int main() {
     6     int n;
     7     cin >> n;
     8     for(int i = 1; i <= n; i++) {
     9       scanf("%d", &a[i]);
    10     }
    11     make_heap(a + 1, a + n + 1);
    12     sort_heap(a + 1, a + n + 1);
    13     for(int i = 1; i <= n; i++) {
    14       printf("%d ", a[i]);
    15     }
    16     return 0;
    17 }
     1 // sort
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<algorithm>
     6 using namespace std;
     7 int n,a[500010];
     8 int main()
     9 {
    10     scanf("%d",&n);
    11     for(int i=1;i<=n;i++)
    12       scanf("%d",&a[i]);
    13     sort(a+1,a+n+1);
    14     for(int i=1;i<=n;i++)
    15       printf("%d ",a[i]);
    16     return 0;
    17 }

    时空如图:

    三次分别是 make_heap/手敲堆/sort。。。。。

    1063 合并果子

    2004年NOIP全国联赛普及组

     时间限制: 1 s    空间限制: 128000 KB    题目等级 : 钻石 Diamond
    题目描述 Description

      在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。


        每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。


        因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。


        例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。

    输入描述 Input Description

     输入包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。

    输出描述 Output Description

    输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。

    样例输入 Sample Input


    1 2 9

    样例输出 Sample Output

    15

    数据范围及提示 Data Size & Hint

    对于30%的数据,保证有n<=1000: 
    对于50%的数据,保证有n<=5000; 
    对于全部的数据,保证有n<=10000。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 using namespace std;
     5 priority_queue <int> que;
     6 int main()
     7 {
     8     int n,x;
     9     scanf("%d",&n);
    10     for(int i=1;i<=n;i++)
    11       scanf("%d",&x),que.push(-x);
    12     int ans=0;
    13     for(int i=1,tmp;i<n;i++)
    14     {
    15         tmp=que.top();
    16         ans-=que.top();
    17         que.pop();
    18         tmp+=que.top();
    19         ans-=que.top();
    20         que.pop();
    21         que.push(tmp);
    22     }
    23     cout<<ans<<endl;
    24     return 0;
    25 }

    1245 最小的N个和

     时间限制: 1 s    空间限制: 128000 KB    题目等级 : 钻石 Diamond
     
    题目描述 Description

    有两个长度为 N 的序列 A 和 B,在 A 和 B 中各任取一个数可以得到 N^2 个和,求这N^2 个和中最小的 N个。

    输入描述 Input Description

    第一行输入一个正整数N;第二行N个整数Ai 且Ai≤10^9;第三行N个整数Bi,
    且Bi≤10^9

    输出描述 Output Description

    输出仅一行,包含 n 个整数,从小到大输出这 N个最小的和,相邻数字之间用
    空格隔开。

    样例输入 Sample Input

    5

    1 3 2 4 5 
    6 3 4 1 7

    样例输出 Sample Output

    2 3 4 4 5

    数据范围及提示 Data Size & Hint

    【数据规模】 对于 100%的数据,满足 1≤N≤100000。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<queue>
     6 
     7 #define maxn 100010
     8 using namespace std;
     9 priority_queue<int,vector<int> > q;// 大头堆 专业建法 
    10 int n,a[maxn],b[maxn],ans[maxn];
    11 int main()
    12 {
    13     scanf("%d",&n);
    14     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    15     for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    16     sort(a+1,a+1+n);sort(b+1,b+1+n);
    17     int p=2,cnt=0;
    18     for(int i=1;i<=n;i++) q.push(b[1]+a[i]);
    19     for(int i=1;i<=n;i++){
    20         while(p<=n&&a[i]+b[p]<q.top()){
    21             q.pop();
    22             q.push(a[i]+b[p]);
    23             p++;
    24         }
    25         p=2;
    26     }
    27     for(int i=n;i>=1;i--){
    28         ans[i]=q.top();
    29         q.pop();
    30     }
    31     for(int i=1;i<=n;i++) printf("%d ",ans[i]);
    32     return 0;
    33 }

    1246 丑数  USACO

     时间限制: 1 s    空间限制: 128000 KB    题目等级 : 钻石 Diamond
    题目描述 Description

    对于一给定的素数集合 S = {p1, p2, ..., pK}, 
    来考虑那些质因数全部属于S 的数的集合。这个集合包括,p1, p1p2, p1p1, 和 p1p2p3 (还有其它)。这是个对于一个输入的S的丑数集合。
    注意:我们不认为1 是一个丑数。
    你的工作是对于输入的集合S去寻找集合中的第N个丑数。longint(signed 32-bit)对于程序是足够的。

    输入描述 Input Description

    第 1 行: 二个被空间分开的整数:K 和 N , 1<= K<=100 , 1<= N<=100,000. 
    第 2 行: K 个被空间分开的整数:集合S的元素

    输出描述 Output Description

    单独的一行,写上对于输入的S的第N个丑数。

    样例输入 Sample Input

    4 19
    2 3 5 7

    样例输出 Sample Output

    27

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 long long p[105],s[100005];
     6 int k,n;
     7 int main()
     8 {
     9     memset(s,0x7f,sizeof(s)); 
    10     scanf("%d%d",&k,&n);
    11     for(int i=1;i<=k;i++)
    12       scanf("%d",&p[i]);
    13     s[0]=1;
    14     for(int i=1;i<=n;i++){
    15         for(int j=1;j<=k;j++){
    16             int l=0,r=i-1,mid;
    17             while(l<r){
    18                 mid=(l+r)/2;
    19                 if(s[mid]*p[j]>s[i-1]) r=mid;
    20                 else l=mid+1;
    21             }
    22             s[i]=min(s[i],s[r]*p[j]);
    23         }
    24     }
    25     printf("%d
    ",s[n]);
    26     return 0;
    27 }

    3377 [Mz]接水问题2

     时间限制: 1 s    空间限制: 64000 KB    题目等级 : 钻石 Diamond
    题目描述 Description

    学校里有一个水房,水房里一共装有m个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为1。

    现在有n名同学准备接水,他们的初始接水顺序已经确定。将这些同学按接水顺序从 1到n编号,i号同学的接水量为wi。接水开始时,1到m号同学各占一个水龙头,并同时打开水龙头接水。当其中某名同学j完成其接水量要求wj后,下一名排队等候接水的同学k马上接替j同学的位置开始接水。这个换人的过程是瞬间完成的,且没有任何水的浪费。即j同学第x秒结束时完成接水,则k同学第x+1秒立刻开始接水。若当前接水人数n’不足m,则只有n’个龙头供水,其它m-n’个龙头关闭。  

    现在给出n名同学的接水量,按照上述接水规则,问所有同学都接完水需要多少秒。

    特别地,同学们在打水前排好了队,接水所用时间更长的先接。

    (ps:出题人本来想设计一个贪心的题目,然后发现用贪心做有反例,只能强改题目,在此声明道歉。不要在意样例解释。)

    输入描述 Input Description

    第 1 行2 个整数 n 和 m,用一个空格隔开,分别表示接水人数和龙头个数。  

    第 2 行 n 个整数 w1、w2、„„、wn,每两个整数之间用一个空格隔开,wi表示 i 号同学的接水量。 

    输出描述 Output Description

    输出只有一行,1 个整数,表示接水所需的总时间。

    样例输入 Sample Input

    5 3

    4 4 1 2 1

    样例输出 Sample Output

    4

    数据范围及提示 Data Size & Hint

    【输入输出解释】

    第 1 秒,3 人接水。第 1秒结束时,1、2、3 号同学每人的已接水量为 1,3 号同学接完水,4 号同学接替 3 号同学开始接水。  

    第 2 秒,3 人接水。第 2 秒结束时,1、2 号同学每人的已接水量为 2,4 号同学的已接水量为 1。  

    第 3 秒,3 人接水。第 3 秒结束时,1、2 号同学每人的已接水量为 3,4 号同学的已接水量为 2。4号同学接完水,5 号同学接替 4 号同学开始接水。  

    第 4 秒,3 人接水。第 4 秒结束时,1、2 号同学每人的已接水量为 4,5 号同学的已接水量为 1。1、2、5 号同学接完水,即所有人完成接水。 

    【数据范围】
    对于 30%的数据,n≤10,000,m≤1,000;
    对于全部的数据,1≤m≤n≤1,000,000,1≤m≤100,000。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<queue>
     6 #define maxn 100010
     7 using namespace std;
     8 struct cmp{
     9     bool operator()(int &a,int &b){
    10         return a>b;
    11     }
    12 };
    13 priority_queue<int,vector<int>,cmp> q; 
    14 int n,m,x,a[1000000+2];
    15 int main()
    16 {
    17     scanf("%d%d",&n,&m);
    18     for(int i=1;i<=n;i++)
    19       scanf("%d",&a[i]);
    20     sort(a+1,a+n+1); 
    21     for(int i=1;i<=m;i++){
    22         q.push(0);
    23     }
    24     for(int i=n;i>=1;i--){
    25         int t=q.top();q.pop();
    26         t+=a[i];
    27         q.push(t);
    28     }
    29     int maxx=0;
    30     while(!q.empty()){
    31         maxx=max(maxx,q.top());
    32         q.pop();
    33     }
    34     
    35     printf("%d",maxx);
    36     return 0;
    37 }

    很没意思的一道题~~

    2830 蓬莱山辉夜

     时间限制: 1 s    空间限制: 32000 KB    题目等级 : 黄金 Gold
    题目描述 Description

    在幻想乡中,蓬莱山辉夜是月球公主,居住在永远亭上,二次设定说她成天宅在家里玩电脑,亦称NEET姬
    一天,她要她帮忙升级月球的网络服务器,应为注册用户过多(月兔和地球上的巫女都注册了……),所以作为代理管理员(俗称网管)的她,非常蛋疼。
    注册用户格式:
    TouhouMaiden 2004 200
    其中前面的Touhoumaiden是预设,不做更改,第一个数是标识,第二个数是每次接受信息访问的间隔用时。
    你要做的事,就是给定一群用户及n,求出这n次信息访问中,访问到了谁?

    presented by Izayoi sakuya

    输入描述 Input Description

    以题目预设格式输入,另起一行以‘#’结束,在其一行输入n

    输出描述 Output Description

    n行,每行输出第行次后,信息访问到了谁?若在一个时间有若干少女被访问到,输出字典序最小的那位少女的标识

    样例输入 Sample Input
    TouhouMaiden 2004 200
    TouhouMaiden 2005 300
    #
    5
    样例输出 Sample Output
    2004
    2005
    2004
    2004
    2005
    数据范围及提示 Data Size & Hint

    标识和每次信息访问间隔均在integer内,n<=10000

    原本是要用到堆,但深搜+时间即可搞定

    数据有点少但也都够变态了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 using namespace std;
     5 struct kaguya{
     6     int time;
     7     int code;
     8     int now;
     9 } baka,mokou;
    10 bool operator<(kaguya a,kaguya b)
    11 {
    12     if(a.now!=b.now)
    13         return a.now>b.now;
    14     else
    15         return a.code>b.code;
    16 }
    17 int main()
    18 {
    19     priority_queue<kaguya> q;
    20     int n;
    21     string a;
    22     while(cin>>a)
    23     {
    24         if(a=="#")break;
    25         cin>>baka.code>>baka.time;
    26         baka.now=baka.time;
    27         q.push(baka);
    28     }
    29     cin>>n;
    30     while(n--){
    31         mokou=q.top();
    32         q.pop();
    33         cout<<mokou.code<<endl;
    34         mokou.now+=mokou.time;
    35         q.push(mokou);
    36     }
    37     return 0;
    38 }

    基本没读懂题目~~~

  • 相关阅读:
    elasticsearch中多个字段聚合及java实现
    elasticsearch中must和should组合查询
    Hash(哈希/散列)表中冲突处理及命中计算
    PHP代码审计理解(一)----Metinfo5.0变量覆盖
    SSL 3.0 POODLE攻击信息泄露漏洞_CVE-2014-3566
    菜鸡试飞----SRCの信息收集手册
    python3-邮件发送-不同格式
    windows下常用快捷指令记忆
    杂记
    偶然碰到的编码转换技巧--叮!
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6240727.html
Copyright © 2011-2022 走看看