题意:给定一个像素信息,每个像素变化为与周围像素的绝对值的最大值,问变化后的信息是怎样的。
思路:由于像素点是非常多的,直接暴力肯定不行。
题目说了只有1000条像素段,那么对于每个像素段,只要把交界地方拿出来考虑,接着把周围9个全考虑就可以了,最多考虑9000个位置。这样时间上就足够了,然后在查找像素对应位置的值可以用二分实现。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
const int N = 9005;
int w, n, sum, an, pos;
struct Seg {
int value, len, pos;
} s[N], ans[N];
bool cmp(Seg a, Seg b) {
return a.len < b.len;
}
int getnum(int pos) {
int l = 1, r = n;
while (l < r) {
int mid = (l + r) / 2;
if (s[mid].pos > pos) r = mid;
else l = mid + 1;
}
return s[l - 1].value;
}
int cal(int pos) {
int num = getnum(pos), ans = 0;
int r = (pos - 1) / w;
int c = (pos - 1) % w;
for (int i = r - 1; i <= r + 1; i++)
for (int j = c - 1; j <= c + 1; j++) {
int v = i * w + j;
if (i < 0 || j < 0 || j >= w || v >= sum || v == pos - 1) continue;
int num2 = getnum(v + 1);
int t = abs(num2 - num);
ans = max(ans, t);
}
return ans;
}
int main() {
while (~scanf("%d", &w) && w) {
n = sum = an = 0;
while (~scanf("%d%d", &s[n].value, &s[n].len) && s[n].value || s[n].len) {
if (n != 0) s[n].pos = s[n - 1].pos + s[n - 1].len;
else s[n].pos = 1;
sum += s[n].len; n++;
}
s[n].len = s[n].value = 0;
s[n].pos = s[n - 1].pos + s[n - 1].len;
for (int k = 0; k <= n; k++) {
int r = (s[k].pos - 1) / w;
int c = (s[k].pos - 1) % w;
for (int i = r - 1; i <= r + 1; i++)
for (int j = c - 1; j <= c + 1; j++) {
int v = i * w + j;
if (i < 0 || j < 0 || j >= w || v >= sum) continue;
ans[an].len = v + 1;
ans[an++].value = cal(v + 1);
}
}
sort(ans, ans + an, cmp);
Seg save = ans[0];
printf("%d\n", w);
for (int i = 0; i < an; i++) {
if (ans[i].value == save.value) continue;
printf("%d %d\n", save.value, ans[i].len - save.len);
save = ans[i];
}
printf("%d %d\n", save.value, sum - save.len + 1);
printf("0 0\n");
}
printf("0\n");
return 0;
}
UVA 1526 - Edge Detection(推理+二分),布布扣,bubuko.com
UVA 1526 - Edge Detection(推理+二分)
原文:http://blog.csdn.net/accelerator_/article/details/22926379