题目:http://codeforces.com/contest/949/problem/D

有二分答案的思路。

如果二分了一个答案,首先可知越靠中间的应该大约越容易满足,因为方便把别的房间的人聚集过来;所以如果二分了答案为 f ,可以认为合法的房间是除了前 f 个和后 f 个的剩下的房间。

但边缘房间自己能满足时也不用专门往中间跑,但一旦要跑,方向一定是向中间的;所以可以用指针判断;

可以认为 f 是合法房间的一个界限;指针走的时候累计一下已经有多少人,当又满足一个房间时,如果指针在界限 f 之前,说明指针后面的房间的人都不用动;而指针前面房间的人一定能赶上跑到那个房间(最差就是被挤着一个一个房间地走),所以不会在时间上不合法;如果指针在界限 f 之后,说明界限到指针之间房间的相应人数要跑到界限这个房间(每次合法一对房间(前面和后面一起做),界限向中间移动一格),这时要判断一下时间来得及否;时间就是从开头到查到界限 f 这个房间的总用时(从题解上可以看出题意好像是先跑一个单位时间,然后再查一个单位时间;即查 i 房间之前有 i 个单位时间)。

如果一直没有不合法,因为是按人数调指针的,所以一定恰好弄完所有人,最后就是合法的。

先放一份cf上的有自己注释的题解代码:

#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cmath>
#include <algorithm> using namespace std; #define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define SZ(a) a.size()
#define LL long long const LL mod = ; int n,d,b;
int a[];
int A[]; bool ok(int num)
{
FOR (i,,n) A[i] = a[i];
LL f1 = num, f2 = n-num-, s1 = , s2 = n-;
//f1:左边第一个需要合法的(从0标号) f2:右边第一个需要合法的
while (f1 < f2)
{
int val, N;
N = b;
while (N && s1-f1 <= 1LL*d*(f1+)) {val = min(A[s1],N), N-= val, A[s1] -= val; if (A[s1] == ) s1++;}
if (N) return false;//查完一个合法房间
//s1>f1怎么理解?s1与s2的相交呢?
//s1不会与s2相交。因为它是看人数的。做完(n+1)/2个N的消耗后,所有a刚好被用完,s1与s2在同一个点
//s1>f1也不怕,因为f1和f2只是一个计时的东西。最后s1和s2的交点是自己合法房间分布的中心
//上一行不太对。因为只要合法房间分布的中心不在所有房间的中心,即意味着有一个宿管超额了
//应当认为越靠中心越容易被满足(大约),s1>f1意味着从后面找人走过来
//s1是指针,就能前一段给f1,之后一段给f1+1……这样贪心
//其实f1的意义是保证f1和它前面的点中这一回有一个合法房间。s1<=f1时相当于没记时间,就是这个意思,
//为了不浪费边界房间
N = b;
while (N && f2-s2 <= 1LL*d*(f1+)) {val = min(A[s2],N), N-= val, A[s2] -= val; if (A[s2] == ) s2--;}
if (N) return false;
f1++; f2--;//自己剩余的合法限度(一旦某个房间合法的过程中使得后面没有足够房间,就崩)
//没有上述情况地做到最后,因为总人数是符合的,所以可以满足
}
return true;
} int main()
{
scanf("%d%d%d",&n,&d,&b);
//n = 4; d = 3; b = 1; a[0] = n*b;
FOR (i,,n) scanf("%d",a+i);
int l = , r = (n+)/;
while (l != r)
{
int x = (l+r)/;
if (ok(x)) r = x;
else l = x+;
}
cout << l;
}

再放上自己的学习(抄)成果:(注意a数组会改变,要每次赋回原值)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1e5+;
int n,d,b,lm,a[N],c[N],l,r,ans,p0,p1,s;
ll dis;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='') ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return fx?ret:-ret;
}
bool check(int f)
{
dis=(ll)d*f; p0=; p1=n;
for(int i=f+;i<=lm;i++)
{
dis+=d; s=b;
while(a[p0]<s)s-=a[p0++]; a[p0]-=s;
if(p0-i>dis)return ; if(i==lm&&(n&))break;
s=b;
while(a[p1]<s)s-=a[p1--]; a[p1]-=s;
if((n-i+)-p1>dis)return ;
}
return ;
}
int main()
{
n=rdn(); d=rdn(); b=rdn(); lm=(n+)>>;
for(int i=;i<=n;i++) c[i]=a[i]=rdn();
l=; r=n+;
while(l<=r)
{
int mid=l+r>>;
memcpy(a,c,sizeof c);
if(check(mid)) ans=mid,r=mid-;
else l=mid+;
}
printf("%d\n",ans);
return ;
}

CF 949D Curfew——贪心(思路!!!)的更多相关文章

  1. hrbust-1909理工门外的树,不用线段数,贪心思路~~

    理工门外的树 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 605(125 users) Total Accepted: 154(11 ...

  2. CF 463A && 463B 贪心 && 463C 霍夫曼树 && 463D 树形dp && 463E 线段树

    http://codeforces.com/contest/462 A:Appleman and Easy Task 要求是否全部的字符都挨着偶数个'o' #include <cstdio> ...

  3. cf 之lis+贪心+思维+并查集

    https://codeforces.com/contest/1257/problem/E 题意:有三个集合集合里面的数字可以随意变换位置,不同集合的数字,如从第一个A集合取一个数字到B集合那操作数+ ...

  4. CF Covered Path (贪心)

    Covered Path time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  5. CF 389 E 贪心(第一次遇到这么水的E)

    http://codeforces.com/contest/389/problem/E 这道题目刚开始想的特别麻烦...但是没想到竟然是贪心 我们只需要知道偶数的时候可以对称取的,然后奇数的时候没次取 ...

  6. LeetCode 423. Reconstruct Original Digits from English——学会观察,贪心思路

    Given a non-empty string containing an out-of-order English representation of digits 0-9, output the ...

  7. 【BZOJ1124】[POI2008]枪战Maf 贪心+思路题

    [BZOJ1124][POI2008]枪战Maf Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开 ...

  8. BZOJ3174 Tjoi2013 拯救小矮人(贪心+DP)

    传送门 Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个 ...

  9. uva 11134 fabled rooks (贪心)——yhx

    We would like to place n rooks, 1 n 5000, on a n nboard subject to the following restrictions• The i ...

随机推荐

  1. Java学习之路 第四篇 oop和class (面向对象和类)

    本人水平有限,创作本文是为了记录学习和帮助初学者学习,欢迎指正和补充 一.面向对象编程的设计概述 很多同学都在学校学了电脑的编程,现在的书籍大部分都是oop面向对象编程,一个很抽象的的名字,比较难以理 ...

  2. Android 手机怎么录屏制成gif图片(电脑录制gif图)

    参考:http://www.cnblogs.com/dasusu/p/4903511.html 上面的博主说的很详细了,但作为学习记录我就重新写一遍帮助自己加深记忆 一.准备条件 1.你搭建了Andr ...

  3. 实模式切换到保护模式,为什么要开启A20地址线(系统升级产生的兼容性问题)

    [-1]写在前面: 以下部分内容总结于 http://blog.csdn.net/ruyanhai/article/details/7181842 complementary: 兼容性是指运行在前期C ...

  4. Vue 填坑系列(持续更新...)

    1.遇到页面显示不更新,数据已更新情况 vue-cli中: this.$nextTick(function () { this.x=x; })     以js引入vue的网页中: this.$set( ...

  5. ArcGIS Overview Map(鹰眼/概览图)

    一.说明 引用文件那块,可以参考我上一篇博文,arcgis api for javascript离线部署. 这篇博文中,地图占满整个body 二.运行效果 三.HTML代码 <!DOCTYPE ...

  6. multiple-value uuid.NewV4() in single-value context

    [root@t ~]# go get github.com/aliyun/aliyun-sts-go-sdk/sts# github.com/aliyun/aliyun-sts-go-sdk/sts/ ...

  7. apache vhosts 虚拟主机设置

    编辑vhosts文件:/alidata/server/httpd-2.4.10/conf/extra/httpd-vhosts.conf <VirtualHost *:80> <Lo ...

  8. 20179209《Linux内核原理与分析》第一周作业

    如何揭开Linux操作系统的最大面纱 个人认为,真正理解一个操作系统最根本的就是理解其文件系统结构. 自windows图形界面诞生,国内大多数用户都选择了windows操作系统,很多人觉得window ...

  9. python+NLTK 自然语言学习处理三:如何在nltk/matplotlib中的图片中显示中文

    我们首先来加载我们自己的文本文件,并统计出排名前20的字符频率 if __name__=="__main__": corpus_root='/home/zhf/word' word ...

  10. .htaccess技巧: URL重写(Rewrite)与重定向(Redirect) (转)

    目录 Table of Contents 一.准备开始:mod_rewrite 二.利用.htaccess实现URL重写(rewrite)与URL重定向(redirect) 将.htm页面映射到.ph ...