这道题我是从样例中看出思路了
2 4
0 0 1 1
看这组数据, 输出的是No, 为什么呢?因为两个1之间没有神龙喝水, 所以一定会有水灾。

然后就启发了我,两次同一个湖的降水之间必须至少有一次神龙喝水, 否则就会有水灾。
如果是第一个湖的话那么就看作在第0次有一次降水。

所以每一次找就用二分来找离前一次降水最近的那一次来喝水。

然后我思路是对的, 但是实现的时候想复杂了很多。

因为这个思路涉及不断地修改一个有序的数列, 我就想用vector, 然后用过就标记, 下一次找的时候用

一个while循环来略去标记过的。事实证明很复杂, 很容易写错。

然后看到博客, 看到用一个set来实现,非常的简洁方便, 核心代码非常的短。

因为set本身就是有序的, 同时自带二分, 而且删除很方便。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std; const int MAXN = 1123456;
int ans[MAXN], pre[MAXN], rain[MAXN]; int main()
{
int T, n, m;
scanf("%d", &T); while(T--)
{
memset(pre, 0, sizeof(pre));
memset(ans, 0, sizeof(ans));
set<int> s; scanf("%d%d", &n, &m);
REP(i, 0, m) scanf("%d", &rain[i]); bool ok = true;
REP(i, 0, m)
{
if(rain[i] == 0)
{
s.insert(i);
continue;
} ans[i] = -1;
auto it = s.lower_bound(pre[rain[i]]);
if(it == s.end()) { ok = false; break; } ans[*it] = rain[i];
pre[rain[i]] = i;
s.erase(*it);
} if(!ok) puts("NO");
else
{
puts("YES");
bool first = true;
REP(i, 0, m)
if(ans[i] != -1)
{
if(first) first = false;
else printf(" ");
printf("%d", ans[i]);
}
puts("");
}
} return 0;
}


最新文章

  1. MFC 创建多层目录
  2. 在 ASP.NET MVC 中使用 HTTPS (SSL/TLS) -- 学习
  3. jquery 停止animate动画,并且回复最初状态
  4. MySql 申明变量以及赋值
  5. ContentProvider使用
  6. 增强的PuTTY 以及 自定义主题
  7. Linux信号列表
  8. NOI2002robot
  9. sort命令总结
  10. jquery自动识别输入的都是数字
  11. jQuery之位置坐标图形相关方法
  12. JWTtoken的原理以及在django中的应用
  13. cdnbest节点动态ip配置教程
  14. VIBE(前景检测)
  15. Shell-6--预定义变量
  16. .net视频教程代码之《提交注册内容》
  17. CentOS6.5安装sqlite3
  18. Cocos2d-x3.0 TestCPP文件夹笔记
  19. tms web core 里面调用pascal 过程。
  20. error CS0234: 命名空间“XXX”中不存在类型或命名空间名称“UserInfoVm”(是否缺少程序集引用?)

热门文章

  1. easyUI datagrid表头的合并
  2. HDU 2604 Queuing( 递推关系 + 矩阵快速幂 )
  3. HDU 1756 Cupid&#39;s Arrow( 判断点在多边形的内外 )
  4. NOI 2015 品酒大会 (后缀数组+并查集)
  5. python 添加自定义库
  6. 【【henuacm2016级暑期训练】动态规划专题 L】Civilization
  7. 洛谷 P2393 yyy loves Maths II
  8. POJ 3749
  9. Tokyo Tyrant(TTServer)系列(二)-启动參数和配置
  10. 自己主动化測试程序之中的一个自己定义键盘的模拟測试程序(C语言)