UVA 11858 Frosh Week 逆序对统计
2016-07-18 01:05
399 查看
题目链接:
http://acm.hust.edu.cn/vjudge/contest/122094#problem/HFrosh Week
Time Limit:8000MSMemory Limit:0KB问题描述
During Frosh Week, students play various fun games to get to know each other and compete against other teams. In one such game, all the frosh on a team stand in a line, and are then asked to arrange themselves according to some criterion, such as their height, their birth date, or their student number. This rearrangement of the line must be accomplished only by successively swapping pairs of consecutive students. The team that finishes fastest wins. Thus, in order to win, you would like to minimize the number of swaps required.
输入
Input contains several test cases. For each test case, the first line of input contains one positive integer n, the number of students on the team, which will be no more than one million. The following n lines each contain one integer, the student number of each student on the team. No student number will appear more than once.
输出
For each test case, output a line containing the minimum number of swaps required to arrange the students in increasing order by student number.
样例
sample input
3
3
1
2
sample output
2
题意
题目其实就是叫你求逆序对的个数
题解
1、数状数组+离散化#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int maxn = 1e6 + 10; typedef long long LL; LL sumv[maxn]; int arr[maxn],ha[maxn]; int n; void add(int x, int v) { while (x <= n) { sumv[x] += v; x += (x&-x); } } LL sum(int x) { LL ret = 0; while (x > 0) { ret += sumv[x]; x -= (x&-x); } return ret; } void init() { memset(sumv, 0, sizeof(sumv)); } int main() { while (scanf("%d", &n) == 1 && n) { init(); LL ans = 0; for (int i = 0; i < n; i++) { scanf("%d", &arr[i]); ha[i] = arr[i]; } sort(ha, ha + n); for (int i = 0; i < n; i++) { int id = lower_bound(ha, ha + n, arr[i]) - ha + 1; ans += sum(n) - sum(id); add(id,1); } printf("%lld\n", ans); } return 0; }
2、分治(归并排序)
#include<iostream> #include<cstdio> #include<vector> using namespace std; typedef long long LL; const int maxn = 1e6 + 10; int n; int arr[maxn]; int tmp[maxn]; LL solve(int l, int r) { if (l == r) return 0; int mid = l + (r - l) / 2; LL ret = 0; ret += solve(l, mid); ret += solve(mid + 1, r); int p = l, p1 = l, p2 = mid + 1; while (p <= r&&p1 <= mid&&p2 <= r) { if (arr[p1] < arr[p2]) { tmp[p++] = arr[p1]; //ret += p2 - mid - 1; p1++; } else { tmp[p++] = arr[p2]; //这里相当于枚举右边的每个元素计算左边比它大的有多少个。 ret += mid - p1 + 1; p2++; } } if (p1 > mid) { while (p2 <= r) tmp[p++] = arr[p2],p2++; } else if (p2 > r) { //ret += (mid - p1 + 1)*(r - mid); while (p1 <= mid) tmp[p++] = arr[p1],p1++; } //printf("(%d,%d):%d\n", l, r, ret); for (int i = l; i <= r; i++) arr[i] = tmp[i]; return ret; } int main() { while (scanf("%d", &n) == 1 && n) { for (int i = 0; i < n; i++) scanf("%d", &arr[i]); LL ans = solve(0, n - 1); //for (int i = 0; i < n; i++) printf("%d ", arr[i]); //puts(""); printf("%lld\n", ans); } return 0; }
相关文章推荐
- 京城游戏人-Day3:对摄像机/屏幕尺寸关系的理解(1)
- 自定义Activity标题栏
- XMLHTTPRequest使用【学习笔记】
- Android权威编程指南学习笔记1
- 监听EditText输入状态,根据是否有输入内容显示ImageButton(清空按钮)
- 371. Sum of Two Integers
- Android 热补丁的一些总结
- 弦图的PERFECT ELIMINATION点排列
- 代码中设置光标显示在EditText文本末尾
- 代码中设置EditText输入类型
- Android JNI初步☞Java方法和native方法关联
- 设置Activity全屏显示
- C语言中%p,%u,%lu都有什么用处
- android实现消息推送的解决方案
- 设置一启动Activity就弹出键盘
- MVC模式的优缺点
- 第三个 android控件
- Google Analytics:为链接点击设定事件追踪的方法
- Activity启动模式
- aidl 进程间通信