微软2014实习生及秋令营技术类职位在线测试第3题
来源:互联网 发布:sql中limit的用法 编辑:程序博客网 时间:2024/06/10 22:12
昨天,有很多同学参加微软2014实习生及秋令营技术类职位在线测试,有些还拿了350分,实在是厉害。
第三题是这样的
- 样例输入
3,1,21,2,3,4,5
- 样例输出
10
Description
Find a pair in an integer array that swapping them would maximally decrease the inversion count of the array. If such a pair exists, return the new inversion count; otherwise returns the original inversion count.
Definition of Inversion: Let (A[0], A[1] ... A[n]) be a sequence of n numbers. If i < j and A[i] > A[j], then the pair (i, j) is called inversion of A.
Example:
Count(Inversion({3, 1, 2})) = Count({3, 1}, {3, 2}) = 2
InversionCountOfSwap({3, 1, 2})=>
{
InversionCount({1, 3, 2}) = 1 <-- swapping 1 with 3, decreases inversion count by 1
InversionCount({2, 1, 3}) = 1 <-- swapping 2 with 3, decreases inversion count by 1
InversionCount({3, 2, 1}) = 3 <-- swapping 1 with 2 , increases inversion count by 1
}
Input
Input consists of multiple cases, one case per line.Each case consists of a sequence of integers separated by comma.
Output
For each case, print exactly one line with the new inversion count or the original inversion count if it cannot be reduced.
就是给我们一个数组,让我们只交换其中的两个元素一次,使得逆序数降低的最多。
最普通的方法,无非是遍历O(n^2),然后每次计算逆序数,复杂度是O(n^4)
稍微改进一下,计算逆序数利用分治法,修改mergesort,复杂度也还是O(n^3*logn)
再稍微改进一下 , 当我们交换a[i]和a[j]时,对i前面和j后面的逆序数不产生影响,只对i,j中间的产生影响,这样的时间复杂度是O(n^3)
今天,我又尝试了一下贪心算法,就是交换改变距离最大的,那么什么是距离最大呢?
比如我有数组5,3,1,2,4
排序完的话是1,2,3,4,5
5,3的距离是0,这是因为5换到3后,距离排序完的5近了一步,但是3换过去距离排序完的3又远了。
5,1的距离是4,交换后都近了2格
#include <iostream>#include <vector>#include <algorithm>#include <map>#include <time.h>using namespace std;int abs(int a,int b){if(a > b)return b-a;return a-b;}int count1(vector<int>& array, int len){int r = 0;for(int i = 0;i < len;i++){for(int j = i+1;j< len;j++){if(array[i] > array[j])r++;}}return r;}int count2(vector<int>& array, int len){vector<int>dup = array;sort(dup.begin(),dup.end());map<int,int>index;for(int i = 0;i<len;i++)index[dup[i]] = i;int r1 = 0,r2 = 0,diff = -1;for(int i = 0;i < len;i++){for(int j = i+1; j < len;j++){if(array[i] > array[j]){int index1 = index[array[i]];int index2 = index[array[j]];int differ1 = abs(index1 - i) - abs(index1 - j);int differ2 = abs(index2 - j) - abs(index2 - i);if((differ1+differ2) > diff){diff = differ1+differ2;r1 = i;r2 = j;}}}}int tmp = array[r1];array[r1] = array[r2];array[r2] = tmp;int count = count1(array,len);return count;}// random generator function:int myrandom (int i) { return std::rand()%i;}int main(int argv, char** args){srand(time(NULL));vector<int>arr;int len = 100;for(int i = 1;i <= len; i++)arr.push_back(i);while(1){random_shuffle(arr.begin(), arr.end(), myrandom);//计算min_count int min_count = count1(arr, len);for(int i = 0;i < len;i++){for(int j = i+1;j < len;j++){if(arr[i] > arr[j]){int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;int count = count1(arr,len);if(min_count > count)min_count = count;tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}}}cout << min_count << endl;//第二种方法int min_count_2 = count2(arr, len);cout << min_count_2 <<endl;if(min_count != min_count_2)break;} return 0;}
这是最原始的方法和贪心算法在一起,当我令数组大小为100,下面是我的输出
2592
2592
2210
2210
2517
2517
2717
2717
2296
2296
2370
2370
2283
2283
2423
2423
2254
2254
2402
2408
昨天同学告诉我他的算法。比如下面是一个数组
6231451079怎么样的数字应该往右交换呢?比如在上面2,3是连续的,更应该选3还是选2?请大家仔细想想
想明白了么?从左边遍历,选6,3,10,9 引文6后面是2,6在这一片最大,然后2,3递增,3最大,然后4,5,10,10最大
什么样的数字应该往左交换呢?
那就从右边往左遍历,寻找区域最小的,也就是7,1,2,6
好了,现在我们有2个集合了,最后的可能性就在集合A选一个集合B选一个
再进行适当的剪枝就能缩小数据大小
- 微软2014实习生及秋令营技术类职位在线测试第3题
- K-th string (微软2014实习生及秋令营技术类职位在线测试题)
- 微软2014实习生及秋令营技术类职位在线测试(第一题)
- 微软2014实习生及校招秋令营技术类职位在线测试第二题
- 微软2014实习生及秋令营技术类职位在线测试第一题:String reorder
- 【微软2014实习生及秋令营技术类职位在线测试】题目3 : Reduce inversion count
- 微软2014实习生及秋令营技术类职位在线测试 String reorder java
- 微软2014实习生及秋令营技术类职位在线测试+试题1+答案
- 微软2014实习生及秋令营技术类职位在线测试-题目1 : String reorder
- 微软2014实习生及秋令营技术类职位在线测试-题目2 : K-th string
- 微软2014实习生及秋令营技术类职位在线测试-题目1 : String reorder
- 微软2014实习生及秋令营技术类职位在线测试 题目1 : String reorder
- 微软2014实习生及校招秋令营技术类职位在线测试:1.String reorder
- 微软2014实习生及秋令营技术类职位在线测试之 2. K-th String
- 微软2014实习生及秋令营技术类职位在线测试返回比赛列表
- 微软2014实习生及秋令营技术类职位在线测试——String reorder
- 微软2014实习生及秋令营技术类职位在线测试——K-th string
- 微软2014实习生及秋令营技术类职位在线测试——Reduce inversion count
- STL 之随机访问迭代器
- 最大报销额 + 0-1背包
- 在TextView中设置超链接、字体、颜色
- jsp注册页面代码
- Hello World! 2010年山东省第一届ACM大学生程序设计竞赛
- 微软2014实习生及秋令营技术类职位在线测试第3题
- Java中hashCode的作用
- Ubuntu下搭建Android Eclipse开发环境
- 2014浙江省赛总结
- UIButton设置为disabled且不变灰的解决方法
- 解决Android手机 屏幕横竖屏切换
- 安装编译环境
- UVA 12050 - Palindrome Numbers(数论+规律)
- HDU 2054 A == B ? (字符串处理)