2016 UESTC Training for Data Structures D - 卿学姐与魔法 CDOJ 1329 堆
2016-05-01 14:12
429 查看
D题:卿学姐与魔法
就是有两个长度为N的序列A和B,N<=1e5,
然后输出A[i]+B[j](i可以等于j)组成的N*N个数中最小的N个
可以用小根堆,也可以不用堆。
用堆的做法,把A数组升序排序,B可排可不排,然后可以得到N个序列
A[0]+B[0],A[1]+B[0],A[2]+B[0]....A[N-1]+B[0]
A[0]+B[1],A[1]+B[1],A[2]+B[1]....A[N-1]+B[1]
.....
A[0]+B[N-1],A[1]+B[N-1],A[2]+B[N-1]....A[N-1]+B[N-1]
然后我们把每个序列的第一个值都放入小根堆中,那么堆顶的元素一定就是最小的元素,假如这个数是A[i]+B[j],然后就把这个数弹出,把A[i+1]+B[j]加入到堆中,调整,然后堆顶元素也一定是最小的,再这样弹出+加入,弹出N个数,这N个数一定是最小的N个数。
我的代码就是这么写的,类似于一种N路归并排序的做法
还有一种做法就是不用堆的做法,
把A数组和B数组都升序排序,
然后设置两个游标i和j,初始i和j都为0,因为A[0]+B[0]一定是最小的,然后后面有两种情况一种是++i,一种是++j,然后选取得到数小的那种,然后就这样啊,移动N次,得到N个数,这N个就是最小的N个数,这种做法我没去验证,但是应该是对的
代码:
就是有两个长度为N的序列A和B,N<=1e5,
然后输出A[i]+B[j](i可以等于j)组成的N*N个数中最小的N个
可以用小根堆,也可以不用堆。
用堆的做法,把A数组升序排序,B可排可不排,然后可以得到N个序列
A[0]+B[0],A[1]+B[0],A[2]+B[0]....A[N-1]+B[0]
A[0]+B[1],A[1]+B[1],A[2]+B[1]....A[N-1]+B[1]
.....
A[0]+B[N-1],A[1]+B[N-1],A[2]+B[N-1]....A[N-1]+B[N-1]
然后我们把每个序列的第一个值都放入小根堆中,那么堆顶的元素一定就是最小的元素,假如这个数是A[i]+B[j],然后就把这个数弹出,把A[i+1]+B[j]加入到堆中,调整,然后堆顶元素也一定是最小的,再这样弹出+加入,弹出N个数,这N个数一定是最小的N个数。
我的代码就是这么写的,类似于一种N路归并排序的做法
还有一种做法就是不用堆的做法,
把A数组和B数组都升序排序,
然后设置两个游标i和j,初始i和j都为0,因为A[0]+B[0]一定是最小的,然后后面有两种情况一种是++i,一种是++j,然后选取得到数小的那种,然后就这样啊,移动N次,得到N个数,这N个就是最小的N个数,这种做法我没去验证,但是应该是对的
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <set> using namespace std; #define ll long long #define maxn 100005 int N, a[maxn], b[maxn], ans[maxn]; struct Node { int num, ai, bi; Node(){} Node(int n, int a, int b) { num = n, ai = a, bi = b; } void make(int n, int a, int b) { num = n, ai = a, bi = b; } bool operator <(Node x)const { return num < x.num; } bool operator >(Node x)const { return num > x.num; } }; Node heap[maxn]; void heap_update() { int k = 1; while (k <= N / 2) { if (heap[k] > heap[2 * k]) { if (heap[k] > heap[2 * k + 1]) { if (heap[2 * k] > heap[2 * k + 1]) { Node t = heap[2 * k + 1]; heap[2 * k + 1] = heap[k]; heap[k] = t; k = 2 * k + 1; } else { Node t = heap[2 * k]; heap[2 * k] = heap[k]; heap[k] = t; k = 2 * k; } } else { Node t = heap[2 * k]; heap[2 * k] = heap[k]; heap[k] = t; k = 2 * k; } } else if (heap[k] > heap[2 * k + 1]) { Node t = heap[2 * k + 1]; heap[2 * k + 1] = heap[k]; heap[k] = t; k = 2 * k + 1; } else break; } } int main() { //freopen("input.txt", "r", stdin); scanf("%d", &N); for (int i = 0; i < N; ++i) scanf("%d", &a[i]); for (int i = 0; i < N; ++i) scanf("%d", &b[i]); sort(a, a + N); sort(b, b + N); for (int i = 0; i < N; ++i) { heap[i + 1].make(a[i] + b[0], i, 0); } for (int i = N; i > 1; --i) { if (heap[i] < heap[i / 2]) { Node t = heap[i / 2]; heap[i / 2] = heap[i]; heap[i] = t; } } for (int i = 0; i < N; ++i) { ans[i] = heap[1].num; heap[1].num = a[heap[1].ai] + b[heap[1].bi + 1]; ++heap[1].bi; heap_update(); } for (int i = 0; i < N; ++i) printf("%d\n", ans[i]); //system("pause"); //while (1); return 0; }
相关文章推荐
- 334. Increasing Triplet Subsequence
- 2016 UESTC Training for Data Structures C - 卿学姐与诡异村庄 CDOJ 1328 并查集
- 2016 UESTC Training for Data Structures B - 卿学姐与基本法 CDOJ 1325 线段树+离散化
- 2016 UESTC Training for Data Structures A - 卿学姐与公主 CDOJ 1324 线段树
- leetcode-225. Implement Stack using Queues
- Codeforces #349 Div2 C Reberland Linguistics(twice in a row)
- requireJS的使用
- Android M 6.0 Build about 64-bit (__arm64__)
- Leetcode:96. Unique Binary Search Trees
- UE4碰撞规则详解
- Xamarin.Android如何异步更新UI线程
- 对BeforeSuite和BeforeTest的理解
- Field 'id' doesn't have a default value
- LeetCode 96.Unique Binary Search Trees
- UIScrollView基本使用(一)
- Increasing Triplet Subsequence
- UIButton、UITextField、UISlider、UISwitch、UISegmentedControl
- HDU 1242 Rescue(图)
- 笔记3:FileWebRequest 与 FileWebResponse
- POJ 2031 Building a Space Station(最小生成树)