洛谷题目
郑航CoderOJ
首先一个很明显的思路就是,从每个输入的点开始,往两边遍历。但是要保证每次遍历不管从那边开始,最终都要相遇,且相遇时候相等或相差1。
所以用一个优先队列,每次从最小的开始遍历就可以了。
但是时间复杂度很高,为nlogn。而且n的数量级是108,数组保存不下,所以空间复杂度爆了。
#include<bits/stdc++.h>
using namespace std;
struct Node {int d, h;bool operator < (const Node b) const {return h > b.h;}
};
vector<int> v,w;
int main() {int n, m;scanf("%d%d", &n, &m);v.resize(n + 1);w.resize(n + 1);priority_queue<Node> q;while(m--) {int d, h;scanf("%d %d", &d, &h);w[d] = h;v[d] = 1;q.push({d, h});}int mx = 0, f = 1;while(!q.empty()) {Node t = q.top();q.pop();mx = max(mx, t.h);if(t.d - 1 > 0) {if(!v[t.d - 1]) {q.push({t.d - 1, t.h + 1});v[t.d - 1] = 1;w[t.d - 1] = t.h + 1;}else if(abs(w[t.d - 1] - w[t.d]) > 1) {f = 0;break;}}if(t.d + 1 <= n) {if(!v[t.d + 1]) {q.push({t.d + 1, t.h + 1});v[t.d + 1] = 1;w[t.d + 1] = t.h + 1;}else if(abs(w[t.d + 1] - w[t.d]) > 1) {f = 0;break;}}}if(f)cout << mx;elseputs("IMPOSSIBLE");return 0;
}
我们可以重新发现:
最后要注意,第一个输入点和最开始可能组成一个最大值,最后一个输入点和最后一个点可能组成最大值。
#include<bits/stdc++.h>
using namespace std;
int main() {int n, m, f = 1, mx = 0;scanf("%d %d", &n, &m);int pd, ph;scanf("%d %d", &pd, &ph);mx = max(mx, ph + pd - 1);while(--m) {int d, h;scanf("%d %d", &d, &h);if(abs(ph - h) > (d - pd)) f = 0;mx = max(mx, (ph + h + d - pd) / 2);pd = d, ph = h;}mx = max(mx, n - pd + ph);if(f) printf("%d", mx);else puts("IMPOSSIBLE");return 0;
}
本文发布于:2024-01-28 14:56:10,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17064249788221.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |