二分_Mode(2016swust校赛)
2016-06-06 04:12
218 查看
这里有一个含有n个数的数组a, 你的任务就是找出在数组中出现次数最多的数m。
但是在找这个数之前,你可以做不超过k次操作:
每次操作从数组中选择一个数,然后使它的值增加1。
同一个数可以接受多次操作。
现在你的任务就是对数组a进行不超过k次操作后,使得m的出现次数最多,如果有多种操作情况使得m有多个值,那么你需要找出最小的m。
Description
多组测试数据
第一行一个整数T ( T ≤ 40 ),表示有T组测试数据
每组测试数据第一行有两个整数n ( 1 ≤ n ≤ 105 ),k ( 0 ≤ k ≤ 109 ),分别表示数组a由n个数组成,可以对数组a进行不超过k次操作。
第二行有n个整数a1 , a2 , … , an ( 0 ≤ ai ≤ 109 )
Input
输出两个数——进行k次操作后m的最大出现次数和使出现次数最大的m的最小值
Output
Sample Input
Sample Output
对于测试数据,可以对a1加上1,得到数组2,2,3; 或者对a2加上1,得到数组1,3,3,使得m的出现次数最大,为2次,我们取最小的m值,即2
这道题可以先升序排序,
然后枚举区间的左端点,二分右端点。然后对于该区间判断是否能够在k次内全部处理为区间最大数。这里的判断可以通过前缀数组来O(1)方法判断。这样就可以对于任意左端点的找到最大的可处理区间这样一旦有更大的可处理区间就跟新长度最大值和m值。因为左端点是从左往右所以第一次处理出来的最大长度值对应的m就是最小的m。
注意:数据大小,使用long long
代码:
但是在找这个数之前,你可以做不超过k次操作:
每次操作从数组中选择一个数,然后使它的值增加1。
同一个数可以接受多次操作。
现在你的任务就是对数组a进行不超过k次操作后,使得m的出现次数最多,如果有多种操作情况使得m有多个值,那么你需要找出最小的m。
Description
多组测试数据
第一行一个整数T ( T ≤ 40 ),表示有T组测试数据
每组测试数据第一行有两个整数n ( 1 ≤ n ≤ 105 ),k ( 0 ≤ k ≤ 109 ),分别表示数组a由n个数组成,可以对数组a进行不超过k次操作。
第二行有n个整数a1 , a2 , … , an ( 0 ≤ ai ≤ 109 )
Input
输出两个数——进行k次操作后m的最大出现次数和使出现次数最大的m的最小值
Output
1 2 3 4 | 1 3 1 1 2 3 |
1 2 | 2 2 |
对于测试数据,可以对a1加上1,得到数组2,2,3; 或者对a2加上1,得到数组1,3,3,使得m的出现次数最大,为2次,我们取最小的m值,即2
这道题可以先升序排序,
然后枚举区间的左端点,二分右端点。然后对于该区间判断是否能够在k次内全部处理为区间最大数。这里的判断可以通过前缀数组来O(1)方法判断。这样就可以对于任意左端点的找到最大的可处理区间这样一旦有更大的可处理区间就跟新长度最大值和m值。因为左端点是从左往右所以第一次处理出来的最大长度值对应的m就是最小的m。
注意:数据大小,使用long long
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int arr[100010]; long long pre[100010]; int n, k; bool Solve(int l, int r) { long long sum = (long long)(r - l + 1) * arr[r] - (pre[r] - pre[l - 1]); if (sum <= k) return true; return false; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) scanf("%d", &arr[i]); sort(arr + 1, arr + 1 + n); for (int i = 1; i <= n; i++) pre[i] = arr[i] + pre[i - 1]; int Max = 0, Ans = 0; for (int i = 1; i <= n; i++) { int l = i, r = n; while (l <= r) { int mid = (l + r) >> 1; if (Solve(i, mid)) l = mid + 1; else r = mid - 1; } while (!Solve(i, r))r--; while (r + 1 < n && Solve(i, r + 1))r++; if (r - i + 1 > Max) { Max = r - i + 1; Ans = arr[i + Max - 1]; } } printf("%d %d\n", Max, Ans); } return 0; }
相关文章推荐
- 快速排序里的学问:从猜数字开始
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- Search Insert Position,Search for a Range,Pow(x, n),Sqrt(x)
- Find Minimum in Rotated Sorted Array II
- [LeetCode] Sqrt(x)
- [LeetCode] Pow(x, n)
- [LeetCode] Search Insert Position
- [LeetCode] Search for a Range
- [LeetCode] Search in Rotated Sorted Array
- PAT 1057 Stack (30)
- int sqrt(int x)
- Pow(x, n)
- Find Minimum in Rotated Sorted Array
- Divide Two Integers
- 信息竞赛学习笔记:POJ3579中位数(二分)
- acm解题报告 HDU 2141 Can you find it?
- acm解题报告 HDU 2199 Can you solve this equation?
- acm解题报告 HDU 2899 Strange fuction
- acm解题报告 HDU 1969 Pie
- acm解题报告 HDU 1061 Rightmost Digit