- 题目描述:
- 题意概述:给你n个数组,要你求对于每个数a[i]问它到周围第j个数a[j]且a[j]等于0的距离的最小值。题目保证有解。
- 解题思路:最开始想法是暴力,对于每个元素向左向右延伸一遍更新最小值,成功T了。然后想怎么简化,实际上对于每次出现的0,正着更新一下它左边的非零数的坐标,再倒着更新一下它右边非0数的坐标取最小值即可。具体实现可以用一个栈存下标,如果当前数不是0则入栈,否则把栈内弹出,对于每个栈顶元素它到这个0的距离就是i - top。
- AC代码:
#include <bits/stdc++.h> #define INF 0x3f3f3f3f #define maxn 200100 #define lson root << 1 #define rson root << 1 | 1 #define lent (t[root].r - t[root].l + 1) #define lenl (t[lson].r - t[lson].l + 1) #define lenr (t[rson].r - t[rson].l + 1) #define N 1111 #define eps 1e-6 #define pi acos(-1.0) #define e exp(1.0) using namespace std; const int mod = 1e9 + 7; typedef long long ll; typedef unsigned long long ull; int a[maxn], d[maxn]; stack<int> s; int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); long _begin_time = clock(); #endif int n; while (~scanf("%d", &n)) { fill(d, d + n + 1, INF); while (!s.empty()) s.pop(); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); if (a[i] == 0) { d[i] = 0; while (!s.empty()) { int cur = s.top(); s.pop(); d[cur] =min(d[cur], i - cur); } } else s.push(i); } while (!s.empty()) s.pop(); for (int i = n; i > 0; i--) { if (a[i] == 0) { while (!s.empty()) { int cur = s.top(); s.pop(); d[cur] = min(d[cur], cur - i); } } else s.push(i); } for (int i = 1; i <= n; i++) if (i == 1) printf("%d", d[i]); else printf(" %d", d[i]); puts(""); } #ifndef ONLINE_JUDGE long _end_time = clock(); printf("time = %ld ms.", _end_time - _begin_time); #endif return 0; }
CF - 803B. Distances to Zero - 栈模拟
最新推荐文章于 2024-08-08 15:12:59 发布