題目給的容器很多,1e9,我們遍歷肯定會超時。
但是他給的信息是,m只有3e5,且每次滴水都會滴在有水的地方,水滿了之后也只會擴散到左右有水的地方。也就是說,只有有水的地方才是我們會用到的地方。
所以,我們只需要將有水的地方存起來即可,同時每次水滿了之后會擴散到左右兩個相鄰有水的地方,所以還需要保存每個水滴左右相鄰的水滴的位置。
每次有水滴滿了,就將他加入優先隊列,因為有多個水滴同時滿了的話,從小的開始先擴散。
其他地方請見標注。
100分代碼:
#include<bits/stdc++.h>
using namespace std;const int MAXN = 110;
const int MAXT = 10000;
const int N = 3e5+10;int n , m , c , p;
int vis[N];
map<int , int>mp; // 排序后的位置struct node{int p; // 位置int w; // 數量int pre;// 前驅int nxt;// 后繼
}a[N];
bool cmp(node a , node b){return a.p < b.p;
}int main(){cin >> c >> m >> n;for(int i = 1 ; i <= m ; i++)cin >> a[i].p >> a[i].w;sort(a+1 , a+m+1 , cmp);for(int i = 1 ; i <= m ; i++){a[i].nxt = i+1;a[i].pre = i-1;mp[a[i].p] = i;}int res = m;priority_queue<int , vector<int> , greater<int>> q;for(int i = 1 ; i <= n ; i++){cin >> p;int id = mp[p];a[id].w++;if(a[id].w >= 5){q.push(id);a[id].w = 0;vis[id] = 1;}while(!q.empty()){res--;int x = q.top();q.pop();int pre = a[x].pre;int nxt = a[x].nxt;a[pre].nxt = nxt;a[nxt].pre = pre;if(pre >= 1){a[pre].w++;if(a[pre].w >= 5 && !vis[pre]){q.push(pre);a[pre].w = 0;vis[pre] = 1;}}if(nxt <= m){a[nxt].w++;if(a[nxt].w >= 5 && !vis[nxt]){q.push(nxt);a[nxt].w = 0;vis[nxt] = 1;}}}cout << res << endl;}return 0;
}