题意:
m个坑,n天,起初每个坑都是满的,每天至多有一个坑会下雨,下雨就会满,满了再下就输出no。
在没有雨的时候可以安排龙来喝水,把坑喝空,可行的话输出龙喝水的方案
思路:
边读入边操作,set保存下来所有没有雨的日子。对每一个有雨的日子,找离上一次满水的日子最近的一次没雨的日子,在这个日子喝掉这个坑,然后更新满水的日子(因为今天下了雨),然后删掉这个没雨的日子(因为一个坑只能喝一次),加入答案
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<stack> #include<queue> #include<deque> #include<set> #include<vector> #include<map> #include<functional> #define fst first #define sc second #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lc root<<1 #define rc root<<1|1 #define lowbit(x) ((x)&(-x)) using namespace std; typedef double db; typedef long double ldb; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PI; typedef pair<ll,ll> PLL; const db eps = 1e-6; const int mod = 1e9+7; const int maxn = 2e6+100; const int maxm = 2e6+100; const int inf = 0x3f3f3f3f; const db pi = acos(-1.0); int n; int vis[maxn]; int pre[maxn]; int ans[maxn]; set<int>norain; int main() { int T; scanf("%d", &T); int top; while(T--){ int m, n; scanf("%d %d", &m, &n); int flg = 1; mem(ans, 0); mem(vis, 0); norain.clear(); mem(pre, 0); //int p = 0; for(int i = 0; i < n; i++){ int c; scanf("%d", &c); if(!flg)continue; if(c==0){ norain.insert(i); vis[i] = 1; } else{ set<int>::iterator it = norain.lower_bound(pre[c]); if(it == norain.end()){ flg = 0; continue; } ans[*it] = c; //printf(" %d ", *it); norain.erase(it); pre[c] = i; } //printf("%d ", ans[i]); } if(!flg){ printf("NO "); } else{ printf("YES "); for(int i = 0; i < n; i++){ if(vis[i])printf("%d ", ans[i]); }printf(" "); } } return 0; } /* 4 2 4 0 0 1 1 2 4 0 1 0 2 2 3 0 1 2 2 4 0 0 0 1 */