Countries
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的更多相关文章
- Countries in War -POJ3114Tarjan缩点+SPFA
Countries in War Time Limit: 1000MS Memory Limit: 65536K Description In the year 2050, after differe ...
- android 命名 数组 所有国家 String[] COUNTRIES
static final String[] COUNTRIES = new String[] { "Afghanistan", "Albania", " ...
- 2016北京网络赛 hihocoder 1391 Countries 树状数组
Countries 描述 There are two antagonistic countries, country A and country B. They are in a war, and ...
- hihocoder-1391&&北京网赛09 Countries(优先队列)
题目链接: Countries 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 There are two antagonistic countries, country ...
- POJ 3114 Countries in War(强连通)(缩点)(最短路)
Countries in War Time Limit: 1000MS Memory Limit: 65536K Total Sub ...
- 离线树状数组 hihocoder 1391 Countries
官方题解: // 离线树状数组 hihocoder 1391 Countries #include <iostream> #include <cstdio> #include ...
- hihoCoder 1391 Countries 【预处理+排序+堆】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)
#1391 : Countries 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 There are two antagonistic countries, countr ...
- POJ 3114 Countries in War(强连通+最短路)
POJ 3114 Countries in War 题目链接 题意:给定一个有向图.强连通分支内传送不须要花费,其它有一定花费.每次询问两点的最小花费 思路:强连通缩点后求最短路就可以 代码: #in ...
- Gephi——使用map of countries和Geo Layout实现包含地理坐标的数据可视化
前言: Gephi(以下内容基于0.9.2)比较擅长用来处理社会网络分析,其自身以及插件对地理数据的支持非常不足.主要有以下几点: 1.map of countries这个插件可以在gephi底图上以 ...
随机推荐
- C语言之位运算
位运算 1).定义. 指的是1个二进制数据的每一位来参与运算. 位运算的前提: 是这个数必须是1个二进制. 注意: a). 参与位运算的二进制数据必须是补码形式. b). 位运算的结果也是二进制的补码 ...
- 快速排序Java版
package Quick; public class quicksort { static class QuickSort { public int data[]; private int part ...
- java的return区别
return ;和return null的区别在于:前者当方法返回值为void时候,return ; 跳出方法. 后者当方法的返回值为object对象时,return null,跳出方法,返回值为空值 ...
- python绝技 — 使用PyGeoIP关联IP地址和物理位置
准备工作 要关联IP与物理位置,我们需要有一个包含这样对应关系的数据库. 我们可以使用开源数据库GeoLiteCity,它能够较为准确地把IP地址与所在城市关联起来 下载地址:http://dev.m ...
- Kali命令集
转载自:http://www.shiyanbar.com/questions/980 系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显 ...
- IIS错误解决办法(HTTP Error 500.19 - Internal Server Error)
window10 切换登陆用户,VS2015的IIS Express 调试代码报HTTP Error 500.19 - Internal Server Error 错误,无法读取配置文件解决办法. I ...
- Atom编辑器之加快React开发的插件汇总
汇总下比较实用的atom插件[偏react开发的]-- 博主发现这个还是比较全面的! atom-react-autocomplete–项目内,组件名及状态的自动补全 autocomplete-js- ...
- CodeForces 669E Little Artem and Time Machine
树状数组,$map$. 可以理解为开一个数组$f[i][j]$记录:$i$这个数字在时间$j$的操作情况. 操作$1$:$f[x][t]++$.操作$2$:$f[x][t]--$.操作$3$:$f[x ...
- PHP控制连接打印机
一.需求 使用PHP控制连接打印机 现场实时连续打印动态数据 二.配置 php运行环境正确安装(Apache|Nginx + PHP) 下载与php版本对应的php_printer.dll扩展 扩展文 ...
- java中equals方法和contentEquals方法区别
java中,String类里提供了两种字符串的比较方式(算上“==”应该是三种) String line1 = new String("0123456789"); String l ...