USTCOJ 1215 未知星球
2013-09-03 21:27
267 查看
题目链接:http://acm.ustc.edu.cn/ustcoj/problem.php?id=1215
个人觉得是一道好题,大意是给一串数字,循环的(首尾实际上是相接的),求最长的一段使得这段里最大的值减最小值不超过k。下面给出我想的一个nlogn的算法,主要是用ST求RMQ问题,加上二分猜答案思想,我们的序列长度最大值已知,且一旦一个较小的k不可能是解,则更大的更不可能(因为判断一个k是不是解是从头到尾遍历的。)这样二分是logn,验证是这样的,我们利用ST算法预处理,在o(n)时间里求一段区间max - min, 加上最后遍历是n所以是o(n),所以合在一起是nlogn。注意遍历判读是否是解需要考略循环,首尾相接。
代码如下:
个人觉得是一道好题,大意是给一串数字,循环的(首尾实际上是相接的),求最长的一段使得这段里最大的值减最小值不超过k。下面给出我想的一个nlogn的算法,主要是用ST求RMQ问题,加上二分猜答案思想,我们的序列长度最大值已知,且一旦一个较小的k不可能是解,则更大的更不可能(因为判断一个k是不是解是从头到尾遍历的。)这样二分是logn,验证是这样的,我们利用ST算法预处理,在o(n)时间里求一段区间max - min, 加上最后遍历是n所以是o(n),所以合在一起是nlogn。注意遍历判读是否是解需要考略循环,首尾相接。
代码如下:
#include<iostream> #include<cstring> #define mem(a) memset(a, 0, sizeof(a)) using namespace std; const int N = 20005; int a , dm [20], dx [20]; //m min, x max void pre(int n) { int i, j; for (i = 0; i < n; ++i) dm[i][0] = dx[i][0] = a[i]; for (j = 1; (1 << j) <= n; ++j) for (i = 0; i + (1 << j) - 1 < n; ++i) dm[i][j] = min(dm[i][j - 1], dm[i + (1 << (j - 1))][j - 1]), dx[i][j] = max(dx[i][j - 1], dx[i + (1 << (j - 1))][j - 1]); } int qx(int s, int e) { int k = 0; while ((1 << (k + 1)) <= e - s + 1) k++; return max(dx[s][k], dx[e - (1 << k) + 1][k]); } int qm(int s, int e) { int k = 0; while ((1 << (k + 1)) <= e - s + 1) k++; return min(dm[s][k], dm[e - (1 << k) + 1][k]); } int ask(int len, int n, int k) { int i, t; for (i = 0; i < n; ++i) { if (i + len - 1 < n) t = qx(i, i + len - 1) - qm(i, i + len - 1); else t = max(qx(i, n - 1), qx(0, len + i - n - 1)) - min(qm(i, n - 1), qm(0, len + i - n - 1)); if (t <= k) return 1; } return 0; } int bs(int s, int e, int n, int k) { int m = (e + s) >> 1; if (e <= s + 1) return s; else { if (ask(m, n, k)) return bs(m, e, n, k); else return bs(s, m, n, k); } } int main() { int n, k, i; while (cin >> n >> k, n | k) { mem(dx), mem(dm); for (i = 0; i < n; ++i) cin >> a[i]; pre(n); cout << bs(1, n + 1, n, k) << endl; } return 0; }
相关文章推荐
- USTCOJ 1264 Longest ‘V’ sequence
- USTCOJ 1324 Zipper 存储计算结果
- USTCOJ 1388 钻石
- USTCOJ 1281 Unhappy dots 快排模板
- USTCOJ 1366 市长选举(约瑟夫环变种)
- USTCOJ 1106 The Luckiest number,2008 Asia Regional, Hefei, Preliminary
- USTCOJ 1361开灯问题、1362 单词求值、1363 幸福配对
- USTCOJ 1266 Sequence Again
- USTCOJ 1371 island计数
- USTCOJ 1382 毛毛虫
- USTCOJ 1324 Zipper 判断连续出现字符
- USTCOJ 1359 查找中位数 不用排序
- USTCOJ 1271 方程X+2Y+5Z=N非负整数解计数
- USTCOJ 1239 God Created The Integers
- USTCOJ代码查看功能的实现(我的第一个Chrome插件,UstcOjSourceView)
- USTCOJ 1274 K_Star风波
- USTCOJ 1127 Laser in Cuboids (思路+容斥原理)
- USTCOJ 1365 字符串计数
- USTCOJ 1240 黑屋 非位运算版
- USTCOJ 1378/POJ 1664 放苹果 解法