最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

20191105 csp

IT圈 admin 2浏览 0评论

20191105 csp

T1 盘王节(panwang)

(WOJ4793)
【题目背景】
小 Q Q Q同学的家乡是远近闻名的瑶族文化旅游村, 村里最近正在开展传统节日特色活动。为了下届族长选举, 小 Q Q Q正想方设法地拉动自己的导游业绩。这次他拉来了他在月亮中学的同学小 L L L为了传播瑶族文化,你需要和小 L L L一起了解瑶族传统节日知识。
【题目描述】
盘王节是祭祀瑶族祖先盘古王的重大节日。
小L望着眼前的小 Q Q Q穿着盛装,鼓声镲声交错耳边,远古而悠长的音节从小 Q Q Q的口中淌出,仿佛构筑起一条现世与始祖神灵的通路。身旁的舞龙队伍盛大地游行着,小 Q Q Q的一双手突然拉住了小 L L L,他们融进了欢庆的人群中兴奋地共舞,夜空之下烟火绽开,华光渲染了他俩的眼眸,更照亮了少年内心暗暗涌动的情愫……
节日庆典上,小 Q Q Q向小 L L L介绍了一种特色双人益智游戏,以下为游戏的大体内容:
• 双方分为进攻方与防守方。
• 进攻方有 n n n种不同的兵符, 第i 种能力值为 a i a_i ai​,各有 x i x_i xi​个。
• 防守方有 m 1 m1 m1种不同的先灵庇佑的御符,,第 i i i种能力值为 b i b_i bi​, 各有 y i y_i yi​个。
• 防守方还有 m 2 m2 m2种不同的兵符,第 i i i种能力值为 c i c_i ci​各有 z i z_i zi​个。
这个游戏由进攻方主动, 每次可以选择一个兵符击破防守方的任意一个御符或任意一个兵符。

  1. 若进攻御符,不会对对方造成伤害,但如果能力值不低于对方,则可以破除对方这个符咒。
  2. 若进攻兵符,会对对方造成为两者能力值差的伤害,如果能力值不低于对方, 则可以破除对方这个符咒。
    注意:
    • 自己的符咒是消耗品,每个只能用一次。
    • 如果自己的符能力值小于对方,视作无效操作且也会浪费当前符咒。
    • 当对方所有御符都被破除后,自己还剩下的兵符可以越过对方兵符直接对对方造成能力值的伤害。
    你需要最大化进攻方对防守方的伤害。
    【输入格式】
    从文件panwang.in中读入数据。
    第一行三个整数, 表示 n , m 1 , m 2 n, m1, m2 n,m1,m2。
    接下来 n n n行, 一行分别给出 a i , x i a_i, x_i ai​,xi​。
    接下来 m 1 m1 m1行, 一行分别给出 b i , y i b_i, y_i bi​,yi​。
    接下来 m 2 m2 m2行, 一行分别给出 c i , z i c_i, z_i ci​,zi​。
    【输出格式】
    输出到文件panwang.out中。
    一行一个整数, 表示最大伤害
    【样例1输入】
    3 1 3
    15 1
    64 1
    18 1
    9 1
    61 1
    86 1
    57 1
    【样例1输出】
    82
    【样例1解释】
    最优策略为:选择一号兵符破除对方御符后,二三号直接对对方造成伤害。
    【样例2~3】
    见选手目录下的panwang/panwang2 ~ 3.in与panwang/panwang2 ~ 3.ans。
    【数据规模与约定】
    对于所有数据, n ≤ 1 0 6 , m 1 ≤ 1 0 6 , m 2 ≤ 1 0 6 n\le 10^6,m1\le 10^6,m2\le 10^6 n≤106,m1≤106,m2≤106,所有能力值为绝对值小于等于 100 100 100的整数,单个种类的符咒数量不超过 1 0 9 10^9 109。

思路:
发现有两种方式可使伤害最大化。

  1. 只打兵符。
  2. 打御符和能使答案更优的兵符

一、只打兵符:
用自己手上最大的兵符打敌人手上最小的兵符,直到对 a n s ans ans没有贡献为止(即 v a l [ m i n e ] = = v a l [ e m e n y ] val[mine]==val[emeny] val[mine]==val[emeny]),使答案最优。

证明:
a n s ans ans即为 ∑ v a l [ m i n e ] − ∑ v a l [ e m e n y ] \sum val[mine]-\sum val[emeny] ∑val[mine]−∑val[emeny]。发现当 v a l [ m i n e ] < v a l [ e m e n y ] val[mine]\lt val[emeny] val[mine]<val[emeny]时,对答案的贡献为负。

二、打御符和能使答案更优的兵符
首先必将敌人手上的御符打完,不然打御符没有意义, a n s ans ans必定没有方案一优。其次用自己手上能打掉敌人御符的最小兵符打(简单贪心)。最后发现打敌人手上权值为负的兵符比直接打脸优。

实现:
敌人御符打完后,将敌人兵符中插入一个权值为零,数量 I N F INF INF的兵符,再按照方案一操作即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define int long longint in{int s=0,f=1;char x;for(x=getchar();!isdigit(x);x=getchar())    if(x=='-')  f=-1;for( ;isdigit(x);x=getchar())   s=(s<<1)+(s<<3)+(x&15);return s*f;
}const int A=5e6+5;
const int INF=1e18;
int n,m1,m2;
struct Fu{int val,num;inline friend bool operator < (const Fu &x,const Fu &y){if(x.val!=y.val)	return x.val<y.val;return x.num<y.num;}
}ff[A],f1[A],f2[A],u[A],v[A];
int ans1,ans2,ans;inline void fight1(){if(ff[n].val<f1[m1].val)    return;memcpy(u,ff,sizeof(ff));memcpy(v,f1,sizeof(f1));int p=1;for(int i=1;i<=n;i++){if(p>m1)    break;while(u[i].val>=v[p].val&&u[i].num>0&&p<=m1){if(u[i].num>=v[p].num){u[i].num-=v[p].num;v[p].num=0;p++;}if(u[i].num<v[p].num){v[p].num-=u[i].num;u[i].num=0;}}}if(p<=m1)   return;for(int i=1;i<=m2;i++){if(f2[i].val<0) v[i]=f2[i];else{v[i].val=0,v[i].num=INF;break;}}v[m2+1].val=0,v[m2+1].num=INF;p=1;for(int i=n;i>0;i--){if(u[i].val<=v[p].val)  break;while(u[i].val>v[p].val&&u[i].num>0){if(u[i].num>=v[p].num){ans1+=(u[i].val-v[p].val)*v[p].num;u[i].num-=v[p].num;v[p].num=0;p++;}if(u[i].num<v[p].num){ans1+=(u[i].val-v[p].val)*u[i].num;v[p].num-=u[i].num;u[i].num=0;}}}return;
}inline void fight2(){memcpy(u,ff,sizeof(ff));memcpy(v,f2,sizeof(f2));int p=1;for(int i=n;i>0;i--){if(u[i].val<=v[p].val)  break;if(p>m2)    break;while(u[i].val>v[p].val&&u[i].num>0&&p<=m2){if(u[i].num>=v[p].num){ans2+=(u[i].val-v[p].val)*v[p].num;u[i].num-=v[p].num;v[p].num=0;p++;}if(u[i].num<v[p].num){ans2+=(u[i].val-v[p].val)*u[i].num;v[p].num-=u[i].num;u[i].num=0;}}}return;
}signed main(){n=in,m1=in,m2=in;for(int i=1;i<=n;i++)ff[i].val=in,ff[i].num=in;for(int i=1;i<=m1;i++)f1[i].val=in,f1[i].num=in;for(int i=1;i<=m2;i++)f2[i].val=in,f2[i].num=in;sort(ff+1,ff+1+n);sort(f1+1,f1+1+m1);sort(f2+1,f2+1+m2);fight1();fight2();ans=max(ans1,ans2);printf("%lld",ans);return 0;
}

20191105 csp

T1 盘王节(panwang)

(WOJ4793)
【题目背景】
小 Q Q Q同学的家乡是远近闻名的瑶族文化旅游村, 村里最近正在开展传统节日特色活动。为了下届族长选举, 小 Q Q Q正想方设法地拉动自己的导游业绩。这次他拉来了他在月亮中学的同学小 L L L为了传播瑶族文化,你需要和小 L L L一起了解瑶族传统节日知识。
【题目描述】
盘王节是祭祀瑶族祖先盘古王的重大节日。
小L望着眼前的小 Q Q Q穿着盛装,鼓声镲声交错耳边,远古而悠长的音节从小 Q Q Q的口中淌出,仿佛构筑起一条现世与始祖神灵的通路。身旁的舞龙队伍盛大地游行着,小 Q Q Q的一双手突然拉住了小 L L L,他们融进了欢庆的人群中兴奋地共舞,夜空之下烟火绽开,华光渲染了他俩的眼眸,更照亮了少年内心暗暗涌动的情愫……
节日庆典上,小 Q Q Q向小 L L L介绍了一种特色双人益智游戏,以下为游戏的大体内容:
• 双方分为进攻方与防守方。
• 进攻方有 n n n种不同的兵符, 第i 种能力值为 a i a_i ai​,各有 x i x_i xi​个。
• 防守方有 m 1 m1 m1种不同的先灵庇佑的御符,,第 i i i种能力值为 b i b_i bi​, 各有 y i y_i yi​个。
• 防守方还有 m 2 m2 m2种不同的兵符,第 i i i种能力值为 c i c_i ci​各有 z i z_i zi​个。
这个游戏由进攻方主动, 每次可以选择一个兵符击破防守方的任意一个御符或任意一个兵符。

  1. 若进攻御符,不会对对方造成伤害,但如果能力值不低于对方,则可以破除对方这个符咒。
  2. 若进攻兵符,会对对方造成为两者能力值差的伤害,如果能力值不低于对方, 则可以破除对方这个符咒。
    注意:
    • 自己的符咒是消耗品,每个只能用一次。
    • 如果自己的符能力值小于对方,视作无效操作且也会浪费当前符咒。
    • 当对方所有御符都被破除后,自己还剩下的兵符可以越过对方兵符直接对对方造成能力值的伤害。
    你需要最大化进攻方对防守方的伤害。
    【输入格式】
    从文件panwang.in中读入数据。
    第一行三个整数, 表示 n , m 1 , m 2 n, m1, m2 n,m1,m2。
    接下来 n n n行, 一行分别给出 a i , x i a_i, x_i ai​,xi​。
    接下来 m 1 m1 m1行, 一行分别给出 b i , y i b_i, y_i bi​,yi​。
    接下来 m 2 m2 m2行, 一行分别给出 c i , z i c_i, z_i ci​,zi​。
    【输出格式】
    输出到文件panwang.out中。
    一行一个整数, 表示最大伤害
    【样例1输入】
    3 1 3
    15 1
    64 1
    18 1
    9 1
    61 1
    86 1
    57 1
    【样例1输出】
    82
    【样例1解释】
    最优策略为:选择一号兵符破除对方御符后,二三号直接对对方造成伤害。
    【样例2~3】
    见选手目录下的panwang/panwang2 ~ 3.in与panwang/panwang2 ~ 3.ans。
    【数据规模与约定】
    对于所有数据, n ≤ 1 0 6 , m 1 ≤ 1 0 6 , m 2 ≤ 1 0 6 n\le 10^6,m1\le 10^6,m2\le 10^6 n≤106,m1≤106,m2≤106,所有能力值为绝对值小于等于 100 100 100的整数,单个种类的符咒数量不超过 1 0 9 10^9 109。

思路:
发现有两种方式可使伤害最大化。

  1. 只打兵符。
  2. 打御符和能使答案更优的兵符

一、只打兵符:
用自己手上最大的兵符打敌人手上最小的兵符,直到对 a n s ans ans没有贡献为止(即 v a l [ m i n e ] = = v a l [ e m e n y ] val[mine]==val[emeny] val[mine]==val[emeny]),使答案最优。

证明:
a n s ans ans即为 ∑ v a l [ m i n e ] − ∑ v a l [ e m e n y ] \sum val[mine]-\sum val[emeny] ∑val[mine]−∑val[emeny]。发现当 v a l [ m i n e ] < v a l [ e m e n y ] val[mine]\lt val[emeny] val[mine]<val[emeny]时,对答案的贡献为负。

二、打御符和能使答案更优的兵符
首先必将敌人手上的御符打完,不然打御符没有意义, a n s ans ans必定没有方案一优。其次用自己手上能打掉敌人御符的最小兵符打(简单贪心)。最后发现打敌人手上权值为负的兵符比直接打脸优。

实现:
敌人御符打完后,将敌人兵符中插入一个权值为零,数量 I N F INF INF的兵符,再按照方案一操作即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define int long longint in{int s=0,f=1;char x;for(x=getchar();!isdigit(x);x=getchar())    if(x=='-')  f=-1;for( ;isdigit(x);x=getchar())   s=(s<<1)+(s<<3)+(x&15);return s*f;
}const int A=5e6+5;
const int INF=1e18;
int n,m1,m2;
struct Fu{int val,num;inline friend bool operator < (const Fu &x,const Fu &y){if(x.val!=y.val)	return x.val<y.val;return x.num<y.num;}
}ff[A],f1[A],f2[A],u[A],v[A];
int ans1,ans2,ans;inline void fight1(){if(ff[n].val<f1[m1].val)    return;memcpy(u,ff,sizeof(ff));memcpy(v,f1,sizeof(f1));int p=1;for(int i=1;i<=n;i++){if(p>m1)    break;while(u[i].val>=v[p].val&&u[i].num>0&&p<=m1){if(u[i].num>=v[p].num){u[i].num-=v[p].num;v[p].num=0;p++;}if(u[i].num<v[p].num){v[p].num-=u[i].num;u[i].num=0;}}}if(p<=m1)   return;for(int i=1;i<=m2;i++){if(f2[i].val<0) v[i]=f2[i];else{v[i].val=0,v[i].num=INF;break;}}v[m2+1].val=0,v[m2+1].num=INF;p=1;for(int i=n;i>0;i--){if(u[i].val<=v[p].val)  break;while(u[i].val>v[p].val&&u[i].num>0){if(u[i].num>=v[p].num){ans1+=(u[i].val-v[p].val)*v[p].num;u[i].num-=v[p].num;v[p].num=0;p++;}if(u[i].num<v[p].num){ans1+=(u[i].val-v[p].val)*u[i].num;v[p].num-=u[i].num;u[i].num=0;}}}return;
}inline void fight2(){memcpy(u,ff,sizeof(ff));memcpy(v,f2,sizeof(f2));int p=1;for(int i=n;i>0;i--){if(u[i].val<=v[p].val)  break;if(p>m2)    break;while(u[i].val>v[p].val&&u[i].num>0&&p<=m2){if(u[i].num>=v[p].num){ans2+=(u[i].val-v[p].val)*v[p].num;u[i].num-=v[p].num;v[p].num=0;p++;}if(u[i].num<v[p].num){ans2+=(u[i].val-v[p].val)*u[i].num;v[p].num-=u[i].num;u[i].num=0;}}}return;
}signed main(){n=in,m1=in,m2=in;for(int i=1;i<=n;i++)ff[i].val=in,ff[i].num=in;for(int i=1;i<=m1;i++)f1[i].val=in,f1[i].num=in;for(int i=1;i<=m2;i++)f2[i].val=in,f2[i].num=in;sort(ff+1,ff+1+n);sort(f1+1,f1+1+m1);sort(f2+1,f2+1+m2);fight1();fight2();ans=max(ans1,ans2);printf("%lld",ans);return 0;
}

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论