3661: Hungry Rabbit

Time Limit: 100 Sec  Memory Limit: 512 MBSec  Special Judge
Submit: 67  Solved: 47

Description

可怕的洪水在夏天不期而至,兔子王国遭遇了前所未有的饥荒,它们不得不去外面的森林里寻找食物。
为了简化起见,我们假设兔子王国中有n只兔子,编号为1n。在救济粮到来之前的m天中,每天恰好有k只兔子需要去森林里寻找粮食。森林里居住着可怕的大灰狼,所幸兔子已经摸清了大灰狼捕食习惯,即狼们在每一天只会捕食特定编号的兔子。为了安全起见,兔子们需要保证每次出去觅食的k只兔子都不会被狼捕食。由于每天出去捕食的兔子都不尽相同,它们为每一天定义了一个生疏度pi,即第i天出来寻找食物,但是第i1天却没有出来觅食的兔子个数。规定第1天的生疏度为0.现在兔子们希望在保证安全的前提下,每天的生疏度不能超过L,请为兔子们构造一个合法的方案。

Input

第一行包括四个整数n,m,k和L.
接下来n行,每行一个长度为m的01串。其中第i行第j个字符若为0,则表示狼在第j天会捕食编号为i的兔子,为1则表示不捕食。

Output

m行,每行k个1-n之间互不相同的整数,代表这一天出去寻找食物的兔子编号。如果没有合法方案,则输出一行1即可。

Sample Input

5 4 3 1
1001
1101
1111
1110
0111

Sample Output

2 3 4
2 3 4
3 4 5
2 3 5

HINT

对于 100% 的测试数据,1 <= n;m <= 800; 1 <= k <= n; 1 <= l <= k

Source

 
【分析】
  
  唉、、、我打了网络流,70分。。。【其实数据弱恰好我数组开小本来90分的。。
  说说我的网络流打法吧,毕竟想了很久。
  就是1100011的兔子可以看成两只1100000、0000011的兔子。
  然后就是说每个兔子表示一个区间,表示它可以从l~r这几天工作。
  就是要找若干个区间覆盖全区间k次。
  就类似这样子的建图:
  
  拆点那里的点容限制了<=L次交换。反向INF表示区间相交求并集。然后判断是否满流就是否有解。
  然后有意义的表示区间的边就是答案,输出即可。【好像输出答案有点困难啊??
 
  然后正解是贪心!【表示考场上想过不知道为什么脑抽觉得n^2log过不了???【黑人问号???
  就是每次贪心找尽量长的区间。。。
  有优先队列维护,每次用最优的更新最差的看看是否成立即可。
 
 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 810
#define INF 0xfffffff struct node
{
int l,r,id;
}t[Maxn*Maxn];
struct cmp{bool operator()(node x,node y){return x.r<y.r;}};
struct cmp2{bool operator()(node x,node y){return x.r>y.r;}};
// bool cmp(node x,node y) {return x.r>y.r;}
// bool cmp2(node x,node y) {return x.r<y.r;}
bool cmp3(node x,node y) {return x.l<y.l;}
priority_queue<node,vector<node>,cmp> q1;
priority_queue<node,vector<node>,cmp2> q2; char s[Maxn]; bool vis[Maxn];
int op[Maxn][Maxn];
int main()
{
// int T;
// scanf("%d",&T);
// while(T--)
{
int n,m,k,l;
scanf("%d%d%d%d",&n,&m,&k,&l); int cnt=,id;
for(int i=;i<=n;i++)
{
scanf("%s",s+);
for(int j=;j<=m;j++)
{
if((j==||s[j-]=='')&&s[j]=='') id=j;
else if(j!=&&s[j-]==''&&s[j]=='') t[++cnt].l=id,t[cnt].r=j-,t[cnt].id=i;
if(s[j]==''&&j==m) t[++cnt].l=id,t[cnt].r=m,t[cnt].id=i;
}
}
sort(t+,t++cnt,cmp3);
// int qz=0;
while(!q1.empty()) q1.pop();
while(!q2.empty()) q2.pop();
int nw=;
bool ok=;
memset(vis,,sizeof(vis));
for(int i=;i<=m;i++)
{
int hh=;
while(t[nw+].l<=i&&nw<cnt) q1.push(t[++nw]);
while(!q2.empty()&&q2.top().r<i) {vis[q2.top().id]=;q2.pop();}
while(q2.size()<k)
{
if(q1.empty()||q1.top().r<i) {ok=;break;}
vis[q1.top().id]=;
q2.push(q1.top());q1.pop();
hh++;
if(hh>l&&i!=) break;
}
if((hh>l&&i!=)||!ok) {ok=;break;}
while(hh<l&&!q1.empty()&&q1.top().r>q2.top().r)
{
hh++;
vis[q2.top().id]=;
q2.pop();
vis[q1.top().id]=;
q2.push(q1.top());q1.pop();
}
op[i][]=;
for(int j=;j<=n;j++) if(vis[j]) op[i][++op[i][]]=j;
}
if(!ok) printf("1\n");
else
{
for(int i=;i<=m;i++)
{
for(int j=;j<=op[i][];j++) printf("%d ",op[i][j]);
printf("\n");
}
}
}
return ;
}

2017-04-24 20:03:42

【BZOJ 3661】 Hungry Rabbit (贪心、优先队列)的更多相关文章

  1. 【BZOJ3661】Hungry Rabbit 贪心

    [BZOJ3661]Hungry Rabbit Description 可怕的洪水在夏天不期而至,兔子王国遭遇了前所未有的饥荒,它们不得不去外面的森林里寻找食物.为了简化起见,我们假设兔子王国中有n只 ...

  2. hihoCoder 1309:任务分配 贪心 优先队列

    #1309 : 任务分配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定 N 项任务的起至时间( S1, E1 ), ( S2, E2 ), ..., ( SN,  ...

  3. UVA 11134 - Fabled Rooks(贪心+优先队列)

    We would like to place  n  rooks, 1 ≤  n  ≤ 5000, on a  n×n  board subject to the following restrict ...

  4. C. Playlist Educational Codeforces Round 62 (Rated for Div. 2) 贪心+优先队列

    C. Playlist time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...

  5. HDU 6438 网络赛 Buy and Resell(贪心 + 优先队列)题解

    思路:维护一个递增队列,如果当天的w比队首大,那么我们给收益增加 w - q.top(),这里的意思可以理解为w对总收益的贡献而不是真正获利的具体数额,这样我们就能求出最大收益.注意一下,如果w对收益 ...

  6. Hungry Rabbit

    Problem C. Hungry Rabbit Input file: hungry.in Output file: hungry.out Time limit: 10 seconds Memory ...

  7. 贪心+优先队列 HDOJ 5360 Hiking

    题目传送门 /* 题意:求邀请顺序使得去爬山的人最多,每个人有去的条件 贪心+优先队列:首先按照l和r从小到大排序,每一次将当前人数相同的被邀请者入队,那么只要能当前人数比最多人数条件小,该人能 被邀 ...

  8. [POJ1456]Supermarket(贪心 + 优先队列 || 并查集)

    传送门 1.贪心 + 优先队列 按照时间排序从前往后 很简单不多说 ——代码 #include <queue> #include <cstdio> #include <i ...

  9. Painting The Fence(贪心+优先队列)

    Painting The Fence(贪心+优先队列) 题目大意:给 m 种数字,一共 n 个,从前往后填,相同的数字最多 k 个在一起,输出构造方案,没有则输出"-1". 解题思 ...

随机推荐

  1. UNIX环境高级编程 第10章 信号

    SIGSTOP和SIGKILL区别是:前者是使进程暂时停止,即中止,也就是说使进程暂停,将进程挂起,比如你在终端里面执行一个脚本或者程序,执行到一半,你想暂停一下,你按下ctrl+z,就会导致终端发送 ...

  2. OGG-01389 File header failed to parse tokens.

    http://blog.csdn.net/zbdba/article/details/44095105; 处理的思路: 1.查看日志 2.在目标端看最新的队列文件的日期,假如没有最新的队列文件就说明源 ...

  3. 洛谷 P4093: bzoj 4553: [HEOI2016/TJOI2016]序列

    题目传送门:洛谷P4093. 题意简述: 给定一个长度为 \(n\) 的序列 \(a\). 同时这个序列还可能发生变化,每一种变化 \((x_i,y_i)\) 对应着 \(a_{x_i}\) 可能变成 ...

  4. Linux MySQl 5.7.17 MySQL ERROR 1366(HY000):Incorrect string value 解决方法

    MySQL ERROR 1366(HY000):Incorrect string value,在往数据库中插入中文的时候会出现. 这也就是编码问题,网上大部分都是说设置下配置文件中的设置,而可悲的是在 ...

  5. 教你用DrawLayout 实现Android 侧滑菜单

    现在的APP越来越注重用户体验,百度视频客户端有一个特效还是挺吸引人的,在主界面手指向右滑动,就可以将菜单展示出来,而主界面会被隐藏大部分,但是仍有左侧的一小部分同菜单一起展示.类似的还有天天动听,人 ...

  6. Gradle教程链接

    Gradle教程:https://www.yiibai.com/gradle/ https://www.cnblogs.com/wxishang1991/p/5532006.html

  7. 在JAVA中记录日志的十个小建议

    JAVA日志管理既是一门科学,又是一门艺术.科学的部分是指了解写日志的工具以及其API,而选择日志的格式,消息的格式,日志记录的内容,哪种消息对应于哪一种日志级别,则完全是基于经验.从过去的实践证明, ...

  8. 【Android开发日记】之入门篇(八)——Android数据存储(下)

    废话不多说了,紧接着来讲数据库的操作吧.Come On! 提到数据存储问题,数据库是不得不提的.数据库是用来存储关系型数据的不二利器.Android为开发者提供了强大的数据库支持,可以用来轻松地构造基 ...

  9. day06作业

    一.方法 1.方法是完成特定功能的代码块. 修饰符  返回值类型  方法类型(参数类型  参数名1,参数类型  参数名2,...){ 方法体语句: return返回值: } 修饰符:目前就用publi ...

  10. thinkphp调试

    Sql调试