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即可.

代码如下:

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #define N 20005
  5 #define R (L+Ta)
  6 using namespace std;
  7 typedef long long LL;
  8 LL Ta,Tb,X,n,m,k,sum,pt;
  9 bool vis[50005];
 10 struct point{
 11     LL times,index,v;
 12 }p[50005];
 13 struct node{
 14     LL fire,fly,dam;
 15     LL l,r;
 16 }launch[N];
 17 bool cmp(point a,point b){
 18     return a.times<b.times;
 19 }
 20 void init(){
 21     sum=0;
 22     memset(vis,0,sizeof(vis));
 23     memset(p,0,sizeof(p));
 24     memset(launch,0,sizeof(launch));
 25     scanf("%I64d",&X);
 26     scanf("%I64d%I64d",&n,&m);
 27     k=pt=0;
 28     for(LL i=0;i<n;++i){
 29         LL a,b,c;
 30         scanf("%I64d%I64d%I64d",&a,&b,&c);
 31         if(X<=a+b&&a+b<=X+Tb){
 32             launch[k].fire=a+b;
 33             launch[k].fly=b;
 34             launch[k].dam=c;
 35             sum+=c;
 36             k++;
 37         }
 38     }
 39     for(LL i=0;i<m;++i){
 40         scanf("%I64d%I64d%I64d",&launch[k].fire,&launch[k].fly,&launch[k].dam);
 41         sum+=launch[k].dam;
 42         k++;
 43     }
 44     for(LL i=0;i<k;++i){
 45         LL fire=launch[i].fire;
 46         LL fly=launch[i].fly;
 47         launch[i].l=fire+fly;
 48         LL t=2*fly;
 49         if(fire+t<X||fire+t>X+Tb){
 50             launch[i].r=launch[i].l;
 51         }else{
 52             LL len=X+Tb-fire;
 53             LL times=len/t;
 54             launch[i].r=launch[i].l+times*t;
 55         }
 56     }
 57     for(LL i=0;i<k;++i){
 58         if(launch[i].r-launch[i].l<=Ta){
 59             p[pt].times=launch[i].l;
 60             p[pt].index=pt/2;
 61             p[pt++].v=launch[i].dam;
 62             p[pt].times=launch[i].r;
 63             p[pt].index=pt/2;
 64             p[pt++].v=launch[i].dam;
 65         }
 66     }
 67     sort(p,p+pt,cmp);
 68 }
 69 int main(void){
 70     while(~scanf("%I64d%I64d",&Ta,&Tb)){
 71         init();
 72         LL Max=0;
 73         LL temp=0;
 74         LL l=0,r=0,L=p[0].times;
 75         /*************防护罩L=p[0].times时的情况*************/
 76         for(;r<pt&&p[r].times<=R;++r){
 77             LL idx=p[r].index;
 78             if(!vis[idx])vis[idx]=1;//[L,R]内有且只有一个idx,即l在[L,R]内
 79             else if(vis[idx]){//如果[L,R]内已经有一个idx,说明当前整个区间[l,r]都在[L,R]内
 80                 vis[idx]=0;
 81                 temp+=p[r].v;
 82             }
 83         }
 84
 85         /*****************将防护罩的L不断右移****************/
 86         if(Max<temp)Max=temp;
 87         while(r<pt){
 88             LL idx=p[l].index;//防护罩L右移,删去l
 89             if(!vis[idx]){//若vis[idx]为零,说明[L,R]中原来有两个idx,即现在[l,r]并不都在[L,R]内
 90                 vis[idx]=1;
 91                 temp-=p[l].v;
 92             }else if(vis[idx])vis[idx]=0;//原来[l,r]就不都在[L,R]内
 93             l++;
 94             while(l<pt&&p[l].times==p[l-1].times){//如果更改后的l与l-1相同,则需要继续处理
 95                 idx=p[l].index;
 96                 if(!vis[idx]){
 97                     vis[idx]=1;
 98                     temp-=p[l].v;
 99                 }else if(vis[idx])vis[idx]=0;
100                 l++;
101             }
102             if(l==pt)break;
103             L=p[l].times;
104             for(;r<pt&&p[r].times<=R;++r){
105                 idx=p[r].index;
106                 if(!vis[idx])vis[idx]=1;
107                 else if(vis[idx]){
108                     vis[idx]=0;
109                     temp+=p[r].v;
110                 }
111             }
112             if(Max<temp)Max=temp;
113         }
114         printf("%I64d\n",sum-Max);
115     }
116 }

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

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

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

代码如下:

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #define N 20005
  5 #define R (L+Ta)
  6 using namespace std;
  7 typedef long long LL;
  8 LL Ta,Tb,X,n,m,k,sum,pt;
  9 bool vis[50005];
 10 struct point{
 11     LL times,index,v;
 12 }p[50005];
 13 struct node{
 14     LL fire,fly,dam;
 15     LL l,r;
 16 }launch[N];
 17 bool cmp(point a,point b){
 18     return a.times<b.times;
 19 }
 20 void init(){
 21     sum=0;
 22     memset(vis,0,sizeof(vis));
 23     memset(p,0,sizeof(p));
 24     memset(launch,0,sizeof(launch));
 25     cin>>X;
 26     cin>>n>>m;
 27     k=pt=0;
 28     for(LL i=0;i<n;++i){
 29         LL a,b,c;
 30         cin>>a>>b>>c;
 31         if(X<=a+b&&a+b<=X+Tb){
 32             launch[k].fire=a+b;
 33             launch[k].fly=b;
 34             launch[k].dam=c;
 35             sum+=c;
 36             k++;
 37         }
 38     }
 39     for(LL i=0;i<m;++i){
 40         cin>>launch[k].fire>>launch[k].fly>>launch[k].dam;
 41         sum+=launch[k].dam;
 42         k++;
 43     }
 44     for(LL i=0;i<k;++i){
 45         LL fire=launch[i].fire;
 46         LL fly=launch[i].fly;
 47         launch[i].l=fire+fly;
 48         LL t=2*fly;
 49         if(fire+t<X||fire+t>X+Tb){
 50             launch[i].r=launch[i].l;
 51         }else{
 52             LL len=X+Tb-fire;
 53             LL times=len/t;
 54             launch[i].r=launch[i].l+times*t;
 55         }
 56     }
 57     for(LL i=0;i<k;++i){
 58         if(launch[i].r-launch[i].l<=Ta){
 59             p[pt].times=launch[i].l;
 60             p[pt].index=pt/2;
 61             p[pt++].v=launch[i].dam;
 62             p[pt].times=launch[i].r;
 63             p[pt].index=pt/2;
 64             p[pt++].v=launch[i].dam;
 65         }
 66     }
 67     sort(p,p+pt,cmp);
 68 }
 69 int main(void){
 70     while(cin>>Ta>>Tb){
 71         init();
 72         LL Max=-1;
 73         LL temp=0;
 74         LL l=0,r=0,L=p[0].times;
 75         for(;r<pt&&p[r].times<=R;++r){
 76             LL idx=p[r].index;
 77             if(!vis[idx])vis[idx]=1;
 78             else if(vis[idx]){
 79                 vis[idx]=0;
 80                 temp+=p[r].v;
 81             }
 82         }
 83         if(Max<temp)Max=temp;
 84         while(r<pt){
 85             LL idx=p[l].index;
 86             if(!vis[idx]){
 87                 vis[idx]=1;
 88                 temp-=p[l].v;
 89             }else if(vis[idx])vis[idx]=0;
 90             l++;
 91             while(l<pt&&p[l].times==p[l-1].times){
 92                 idx=p[l].index;
 93                 if(!vis[idx]){
 94                     vis[idx]=1;
 95                     temp-=p[l].v;
 96                 }else if(vis[idx])vis[idx]=0;
 97                 l++;
 98             }
 99             if(l==pt)break;
100             L=p[l].times;
101             for(;r<pt&&p[r].times<=R;++r){
102                 idx=p[r].index;
103                 if(!vis[idx])vis[idx]=1;
104                 else if(vis[idx]){
105                     vis[idx]=0;
106                     temp+=p[r].v;
107                 }
108             }
109             if(Max<temp)Max=temp;
110         }
111         cout<<sum-Max<<endl;
112     }
113 }
时间: 2024-09-29 23:31:08

Countries的相关文章

LeetCode解题思路:595. Big Countries

There is a table World +-----------------+------------+------------+--------------+---------------+ | name | continent | area | population | gdp | +-----------------+------------+------------+--------------+---------------+ | Afghanistan | Asia | 652

POJ 3114 Countries in War 强连通+最短路

用floyd超时了...注定的事情...题意:看案例就跑出来了..不需要看题了把.. #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #include<vector> const int INF =1999299; int minn(int a,int b) { return a>b?b:a; } #define N 510 #define M

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

#1391 : Countries 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 There are two antagonistic countries, country A and country B. They are in a war, and keep launching missiles towards each other. It is known that country A will launch N missiles. The i-th miss

POJ 3114 - Countries in War(强连通分量+缩点+拓扑排序+DAG最短路)

Countries in War Time Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Appoint description: Description In the year 2050, after different attempts of the UN to maintain peace in the world, the third world war broke out. The impor

离线树状数组 hihocoder 1391 Countries

官方题解: 1 // 离线树状数组 hihocoder 1391 Countries 2 3 #include <iostream> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <math.h> 9 #include <memory.h> 10 using namespace s

595. Big Countries (Easy)

Source: https://leetcode.com/problems/big-countries/#/descriptionDescription: There is a table World +-----------------+------------+------------+--------------+---------------+ | name | continent | area | population | gdp | +-----------------+------

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

POJ 3114 Countries in War 题目链接 题意:给定一个有向图,强连通分支内传送不需要花费,其他有一定花费,每次询问两点的最小花费 思路:强连通缩点后求最短路即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <stack> #include <algorithm> using namespa

595. Big Countries --- SQL related from leetcode

595. Big Countries There is a table World +-----------------+------------+------------+--------------+---------------+ | name | continent | area | population | gdp | +-----------------+------------+------------+--------------+---------------+ | Afgha

以太坊Crypto Countries加密国家火爆,区块链游戏成智能合约应用探索突破口

继加密猫(CryptoKitties)之后,以太坊上又出现了几款火爆的区块链游戏,它们是CryptoCountries,Crypto-All Stars,CryptoCelebrities和EtherBots. 这几款游戏目前的知名度还不如CryptoKitties,不过相信用不了多久,它们中的某一款肯定会比CryptoKitties更有名. 为什么这么说,因为它们是比CryptoKitties更好玩的区块链游戏,或者说是CryptoKitties的进化版.加密猫(CryptoKitties)是