Countries

题目链接:http://hihocoder.com/problemset/problem/1391

预处理+双指针

首先将A->B,B->A的导弹全部转化为B->A的导弹(因为不需要计算B承受的伤害,所以对于A->B的导弹,只需记录被B的防护罩返回来的导弹即可).

然后对于每个导弹计算将其反弹回B,A所需要的最小的防护罩区间[l,r](这个操作在O(1)的时间完成,画张图就很好推了)

于是问题就转化为了:

数轴上有一些固定区间,每个固定区间都有一个权值,现在有一个长度为Ta的防护罩区间,问用这个防护罩区间完整包含的固定区间的权值和最大为多少?

对于这个问题,可以将固定区间的左右两端点标号,存到一个数组(struct{int position,index,value;}),然后用一个vis数组标记第index个固定区间在防护罩区间内的情况,遍历一遍防护罩区间的L即可.

代码如下:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#define N 20005
#define R (L+Ta)
using namespace std;
typedef long long LL;
LL Ta,Tb,X,n,m,k,sum,pt;
bool vis[];
struct point{
LL times,index,v;
}p[];
struct node{
LL fire,fly,dam;
LL l,r;
}launch[N];
bool cmp(point a,point b){
return a.times<b.times;
}
void init(){
sum=;
memset(vis,,sizeof(vis));
memset(p,,sizeof(p));
memset(launch,,sizeof(launch));
scanf("%I64d",&X);
scanf("%I64d%I64d",&n,&m);
k=pt=;
for(LL i=;i<n;++i){
LL a,b,c;
scanf("%I64d%I64d%I64d",&a,&b,&c);
if(X<=a+b&&a+b<=X+Tb){
launch[k].fire=a+b;
launch[k].fly=b;
launch[k].dam=c;
sum+=c;
k++;
}
}
for(LL i=;i<m;++i){
scanf("%I64d%I64d%I64d",&launch[k].fire,&launch[k].fly,&launch[k].dam);
sum+=launch[k].dam;
k++;
}
for(LL i=;i<k;++i){
LL fire=launch[i].fire;
LL fly=launch[i].fly;
launch[i].l=fire+fly;
LL t=*fly;
if(fire+t<X||fire+t>X+Tb){
launch[i].r=launch[i].l;
}else{
LL len=X+Tb-fire;
LL times=len/t;
launch[i].r=launch[i].l+times*t;
}
}
for(LL i=;i<k;++i){
if(launch[i].r-launch[i].l<=Ta){
p[pt].times=launch[i].l;
p[pt].index=pt/;
p[pt++].v=launch[i].dam;
p[pt].times=launch[i].r;
p[pt].index=pt/;
p[pt++].v=launch[i].dam;
}
}
sort(p,p+pt,cmp);
}
int main(void){
while(~scanf("%I64d%I64d",&Ta,&Tb)){
init();
LL Max=;
LL temp=;
LL l=,r=,L=p[].times;
/*************防护罩L=p[0].times时的情况*************/
for(;r<pt&&p[r].times<=R;++r){
LL idx=p[r].index;
if(!vis[idx])vis[idx]=;//[L,R]内有且只有一个idx,即l在[L,R]内
else if(vis[idx]){//如果[L,R]内已经有一个idx,说明当前整个区间[l,r]都在[L,R]内
vis[idx]=;
temp+=p[r].v;
}
} /*****************将防护罩的L不断右移****************/
if(Max<temp)Max=temp;
while(r<pt){
LL idx=p[l].index;//防护罩L右移,删去l
if(!vis[idx]){//若vis[idx]为零,说明[L,R]中原来有两个idx,即现在[l,r]并不都在[L,R]内
vis[idx]=;
temp-=p[l].v;
}else if(vis[idx])vis[idx]=;//原来[l,r]就不都在[L,R]内
l++;
while(l<pt&&p[l].times==p[l-].times){//如果更改后的l与l-1相同,则需要继续处理
idx=p[l].index;
if(!vis[idx]){
vis[idx]=;
temp-=p[l].v;
}else if(vis[idx])vis[idx]=;
l++;
}
if(l==pt)break;
L=p[l].times;
for(;r<pt&&p[r].times<=R;++r){
idx=p[r].index;
if(!vis[idx])vis[idx]=;
else if(vis[idx]){
vis[idx]=;
temp+=p[r].v;
}
}
if(Max<temp)Max=temp;
}
printf("%I64d\n",sum-Max);
}
}

然而出了点问题,昨天晚上debug到三点多,一直是WA,会不会写搓了?第二天起来看了好久没看出来,会不会是算法错了?问了游少,他也表示母鸡。

回到寝室,心血来潮把I64d改成lld交了一发:PE.???.jpg

全部改成了cin,cout:AC.浪费了我一天

代码如下:

 #include<iostream>
#include<algorithm>
#include<cstring>
#define N 20005
#define R (L+Ta)
using namespace std;
typedef long long LL;
LL Ta,Tb,X,n,m,k,sum,pt;
bool vis[];
struct point{
LL times,index,v;
}p[];
struct node{
LL fire,fly,dam;
LL l,r;
}launch[N];
bool cmp(point a,point b){
return a.times<b.times;
}
void init(){
sum=;
memset(vis,,sizeof(vis));
memset(p,,sizeof(p));
memset(launch,,sizeof(launch));
cin>>X;
cin>>n>>m;
k=pt=;
for(LL i=;i<n;++i){
LL a,b,c;
cin>>a>>b>>c;
if(X<=a+b&&a+b<=X+Tb){
launch[k].fire=a+b;
launch[k].fly=b;
launch[k].dam=c;
sum+=c;
k++;
}
}
for(LL i=;i<m;++i){
cin>>launch[k].fire>>launch[k].fly>>launch[k].dam;
sum+=launch[k].dam;
k++;
}
for(LL i=;i<k;++i){
LL fire=launch[i].fire;
LL fly=launch[i].fly;
launch[i].l=fire+fly;
LL t=*fly;
if(fire+t<X||fire+t>X+Tb){
launch[i].r=launch[i].l;
}else{
LL len=X+Tb-fire;
LL times=len/t;
launch[i].r=launch[i].l+times*t;
}
}
for(LL i=;i<k;++i){
if(launch[i].r-launch[i].l<=Ta){
p[pt].times=launch[i].l;
p[pt].index=pt/;
p[pt++].v=launch[i].dam;
p[pt].times=launch[i].r;
p[pt].index=pt/;
p[pt++].v=launch[i].dam;
}
}
sort(p,p+pt,cmp);
}
int main(void){
while(cin>>Ta>>Tb){
init();
LL Max=-;
LL temp=;
LL l=,r=,L=p[].times;
for(;r<pt&&p[r].times<=R;++r){
LL idx=p[r].index;
if(!vis[idx])vis[idx]=;
else if(vis[idx]){
vis[idx]=;
temp+=p[r].v;
}
}
if(Max<temp)Max=temp;
while(r<pt){
LL idx=p[l].index;
if(!vis[idx]){
vis[idx]=;
temp-=p[l].v;
}else if(vis[idx])vis[idx]=;
l++;
while(l<pt&&p[l].times==p[l-].times){
idx=p[l].index;
if(!vis[idx]){
vis[idx]=;
temp-=p[l].v;
}else if(vis[idx])vis[idx]=;
l++;
}
if(l==pt)break;
L=p[l].times;
for(;r<pt&&p[r].times<=R;++r){
idx=p[r].index;
if(!vis[idx])vis[idx]=;
else if(vis[idx]){
vis[idx]=;
temp+=p[r].v;
}
}
if(Max<temp)Max=temp;
}
cout<<sum-Max<<endl;
}
}

Countries的更多相关文章

  1. Countries in War -POJ3114Tarjan缩点+SPFA

    Countries in War Time Limit: 1000MS Memory Limit: 65536K Description In the year 2050, after differe ...

  2. android 命名 数组 所有国家 String[] COUNTRIES

    static final String[] COUNTRIES = new String[] { "Afghanistan", "Albania", " ...

  3. 2016北京网络赛 hihocoder 1391 Countries 树状数组

    Countries   描述 There are two antagonistic countries, country A and country B. They are in a war, and ...

  4. hihocoder-1391&&北京网赛09 Countries(优先队列)

    题目链接: Countries 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 There are two antagonistic countries, country ...

  5. POJ 3114 Countries in War(强连通)(缩点)(最短路)

                                    Countries in War Time Limit: 1000MS   Memory Limit: 65536K Total Sub ...

  6. 离线树状数组 hihocoder 1391 Countries

    官方题解: // 离线树状数组 hihocoder 1391 Countries #include <iostream> #include <cstdio> #include ...

  7. hihoCoder 1391 Countries 【预处理+排序+堆】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)

    #1391 : Countries 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 There are two antagonistic countries, countr ...

  8. POJ 3114 Countries in War(强连通+最短路)

    POJ 3114 Countries in War 题目链接 题意:给定一个有向图.强连通分支内传送不须要花费,其它有一定花费.每次询问两点的最小花费 思路:强连通缩点后求最短路就可以 代码: #in ...

  9. Gephi——使用map of countries和Geo Layout实现包含地理坐标的数据可视化

    前言: Gephi(以下内容基于0.9.2)比较擅长用来处理社会网络分析,其自身以及插件对地理数据的支持非常不足.主要有以下几点: 1.map of countries这个插件可以在gephi底图上以 ...

随机推荐

  1. 快速排序Java版

    package Quick; public class quicksort { static class QuickSort { public int data[]; private int part ...

  2. SmoOne——开源免费的企业移动OA应用,基于VS.Net

    一.SmoOne是什么一个开源的移动OA应用 二.语言.Net 三.开发环境Visual Studio 四.开发平台Smobiler Designer 五.功能该应用开源代码中包含注册.登录.用户信息 ...

  3. 【成长之路】【python】python基础1

    1.python的优点 高级语言:不需考虑底层实现的细节 可移植性:python程序不需经过任何修改就可以在所有的平台系统上运行 可扩展性:可以把用c和c++实现的代码嵌到python中 可嵌入性:可 ...

  4. hdu 3842 Machine Works(cdq分治维护凸壳)

    题目链接:hdu 3842 Machine Works 详细题解: HDU 3842 Machine Works cdq分治 斜率优化 细节比较多,好好体会一下. 在维护斜率的时候要考虑x1与x2是否 ...

  5. Elasticsearch 5.0 安装 Search Guard 5 插件 (五)

    一.Search Guard 简介 Search Guard  是 Elasticsearch 的安全插件.它为后端系统(如LDAP或Kerberos)提供身份验证和授权,并向Elasticsearc ...

  6. python流程控制:while循环

    python编程中whihe语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务. while循环语句格式: while <判断条件>: 执行语句 count ...

  7. openstack私有云布署实践【9.3 主从controller单向同步glance-image目录】

    采用Rysnc单向同步,而不用双方实时同步,原因是在历史的运行过程中,我们发现,有些镜像包太大,当在主用的glance将镜像保存时,并不是一时半会就把镜像保存好,当主用在保存时,备用节点又在实时同步那 ...

  8. OSI参考模型初识

    纪念我曾今热爱的数通(^o^). 1.osi参考模型 2.数据的封装和解封装 3.主机和主机间通信

  9. 【angular】angular如何让传递变量参数+ng-change的使用

    HTML: <div class="form-group"> <label class="col-sm-2 control-label"> ...

  10. python 主机宝

    需求:开发一个主机批量管理系统,要求按saltstack方式执行命令 #!/usr/bin/env python3. # -*- coding:utf8 -*- import os,sys,pickl ...