codeforces 485D. Maximum Value

来源:互联网 发布:深圳云计算招聘岗位 编辑:程序博客网 时间:2024/06/05 18:25

题意:给你N个元素,求出这N个元素中a[j]%a[i]的最大值, 且 a[j] ≥ a[i](1 ≤ i, j ≤ N)。

思路:枚举a[i],二分查找a[j]。我们可以发现对于a[i]这个值,a[j]%a[i]的值是如图一个以a[i]为周期的变化过程,所以我们找到一个距k*a[i]最近的那个值便是对于a[i]这个值a[j]%a[i]的最大值。我们先排序然后去重(因为重复的数字对答案没有贡献但是会浪费时间),此时我们枚举a[i],再枚举k,二分查找距离k*a[i]最近的那个值就可以了。

这个复杂度大概也是的具体怎么估的,我也不是很会。。。

排序+去重:

#include<bits/stdc++.h>using namespace std;const int MAXN = 2e5 + 5;int n, a[MAXN];int main() {while(~scanf("%d",&n)){for(int i = 0; i < n; i++) scanf("%d",&a[i]);sort(a, a + n);//排序 n = unique(a, a + n) - a;//去重 int MAX = 0;for(int i = 0; i < n; i++){for(int j = a[i]; j <= a[n - 1]; j += a[i]){int pos = lower_bound(a + i, a + n, a[i] + j) - a - 1;//二分查找 MAX = max(MAX, a[pos] % a[i]); if(MAX == a[i] - 1) break;//a[j]%a[i]最大值为a[i] - 1 }}printf("%d\n",MAX);}return 0;}/*33 4 529 1035 8 10*/


set:
#include<bits/stdc++.h>using namespace std;const int MAXN = 2e5 + 5;int n;int main() {while(~scanf("%d",&n)){set<int> s;//可以排序加去重 for(int i = 0; i < n; i++){int t; scanf("%d",&t);s.insert(t);}set<int>::iterator BACK=s.end();BACK--; int E = *BACK;//获得最后一个元素的值 int MAX = 0;for(set<int>::iterator it = s.begin(); it != s.end(); it++){for(int j = (*it); j <= E; j += (*it)){set<int>::iterator itlow = s.lower_bound((*it) + j);itlow--;//二分查找 MAX = max(MAX, (*itlow) % (*it));if(MAX == (*it) - 1) break;//a[j]%a[i]最大值为a[i] - 1  }}printf("%d\n",MAX);}return 0;}/*33 4 529 1032 8 10*/

看见数据范围知道要才能过,也想到了二分,但是如何二分没想到。哎
原创粉丝点击