不要以为普及组的题就很和谐。。

勇者斗恶龙

一、题目

现在有一条 n 头龙,生命值为 h,勇士想要打败这条作恶多端的龙。

勇士攻击第 i 个头会造成 min(h,atki) 点伤害,即龙的生命值减少 min(h,atki) 点;但龙的第 i 个头受到伤害后会恢复 di 点生命值,即生命值增加 di 。 勇士无法重复攻击同一个头,即他对于每个头最多只能攻击一次。当龙的生命值为 o 时则视为被勇士打败,此时它不能再恢复生命值了。 勇士想要知道他是否能打败这头龙,如果能打败最少需要攻击多少次。

二、解法

0x01 错解及思考
首先先讲一个错解,虽然它是错的,但是可以启发我们。
发现每次攻击完后伤害都是ai−biai-biai−bi(除了最后一击),我们就可以把ai−biai-biai−bi排序,然后贪心取答案。
这个解法有一个局限,就是最后一击是与众不同的,看下面一组反例:
2 1050
50 0
1000 900
如果按上述的贪心算法,那么是得不到答案的,但是我们先取第一击,就可以得到答案。

0x02 贪心的改进
上面的贪心还是比较优秀,现在考虑改进它,我们可以将最后一击拿来枚举,记vi=ai−bivi=ai-bivi=ai−bi,将vivivi从大到小排序处理出一个前缀和,这就给我们提供了二分的条件,注意特别考虑枚举的最后一击在前缀和中的情况,时间复杂度O(nlogn)O(nlogn)O(nlogn)。

0x3f 代码
记得要特判h=0h=0h=0的情况。

#include <cstdio>
#include <algorithm>
using namespace std;
#define int long long
const int MAXN = 300005;
int read()
{int x=0,flag=1;char c;while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*flag;
}
int n,h,ans=0x3f3f3f3f,rank[MAXN],sum[MAXN],a[MAXN],b[MAXN];
struct node
{int v,id;bool operator < (node x) const{return v>x.v;}
}s[MAXN];
signed main()
{n=read();h=read();if(h==0){printf("Yes\n0\n");return 0;}for(int i=1;i<=n;i++){a[i]=read(),b[i]=read();s[i]=node{a[i]-b[i],i};}sort(s+1,s+1+n);for(int i=1;i<=n;i++){sum[i]=sum[i-1]+s[i].v;rank[s[i].id]=i;}for(int i=1;i<=n;i++){int loc=lower_bound(sum+1,sum+1+n,h-a[i])-sum;if(loc>=rank[i])loc=lower_bound(sum+1,sum+1+n,h-b[i])-sum;if(loc==n+1) continue;ans=min(ans,loc+(rank[i]>loc));}if(ans==0x3f3f3f3f)return !puts("No");puts("Yes");printf("%d\n",ans);
}

徒步旅行

一、题目

小 A 决定开始一场奇妙的徒步旅行,旅行地图可以看成是一个平面直角坐标系,小 A 从家 O(0,0) 出发,每一步移动只能由他此时所在的位置 (x,y) 走到以下四个坐标之一:(x-1,y),(x,y-1),(x+1,y),(x,y+1)。现在有 n 个旅游景点,第 i 个旅游景点位置为(xi,yi)。 由于世界如此之大,整个旅行地图被分成了多个不同的气候区,某个景点(xi,yi)的气候区 Ci=max(xi,yi)。小 A 想要更好的了解这个世界使得他这次徒步旅行更有意义,所以他想要去气候区 i+1 旅行当且仅当访问完气候区 i 的所有旅游景点。当他访问完所有的景点时,他会回到家里。 小 A 想让你帮他设计出一条旅游路线使得他移动的步数最少,因为徒步旅行还是比较累的……

二、解法

对于每一个气候,可以发现它的起点和终点最有的取法一定是两个端点,明白这点后直接dpdpdp即可。
注意要考虑两个端点间不经过拐点的情况。

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int MAXN = 300005;
const int INF = 0x3f3f3f3f;
int read()
{int x=0,flag=1;char c;while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*flag;
}
int n,m,dp[MAXN][2];
int abs_(int x)
{return x>0?x:-x;
}
struct point
{int x,y;int  operator * (point oth) const{return abs_(x-oth.x)+abs_(y-oth.y);}bool operator < (point oth) const{return max(x,y)<max(oth.x,oth.y);}
}p[MAXN],l[MAXN],r[MAXN];
signed main()
{n=read();for(int i=1;i<=n;i++)p[i]={read(),read()};sort(p+1,p+1+n);for(int i=1;i<=n;i++){if(p[i-1]<p[i]) {l[++m]=p[i];r[m]=p[i];continue ;}if(p[i].x==max(p[i].x,p[i].y)){if(p[i].y>l[m].y) l[m]=p[i];if(p[i].y<r[m].y) r[m]=p[i];}else{if(p[i].x>r[m].x) r[m]=p[i];if(p[i].x<l[m].x) l[m]=p[i];}}for(int i=1;i<=n;i++){int dis=l[i-1]*r[i-1];dp[i][0]=min(dp[i-1][0]+dis+r[i-1]*l[i],dp[i-1][1]+dis+l[i-1]*l[i]);dp[i][1]=min(dp[i-1][0]+dis+r[i-1]*r[i],dp[i-1][1]+dis+l[i-1]*r[i]);}printf("%lld\n",min(dp[n][0]+point{0,0}*r[n],dp[n][1]+point{0,0}*l[n]));
}

情报机器人

一、题目

点此看题

二、解法

看到这道题,就想到了二分答案,再看能不能生成树,结果只得了80分。
再看题目,发现机器人可以斜着走,所以它并不是一个单调的图像。
再考虑有没有单峰性质呢(其实是有的),下面给出证明:
??????????????????
然后我们可以把它转化成最小生成树问题,用三分解决边权,由于边的个数是O(n2)O(n^2)O(n2)的,选用primprimprim算法,时间复杂度O(n2logn)O(n^2logn)O(n2logn)。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define int long long
const int MAXN = 1005;
const int inf = (1ll<<60);
int read()
{int x=0,flag=1;char c;while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*flag;
}
int n,a,b,fa[MAXN],dis[MAXN],g[MAXN][MAXN],cnt,ans,res;
int dx[9]={0,1,-1,0,0,1,1,-1,-1};
int dy[9]={0,0,0,1,-1,1,-1,1,-1};
int abs_(int x)
{return x>0?x:-x;
}
struct point
{int x,y,d;int operator * (point oth) const{return abs_(x-oth.x)+abs_(y-oth.y);}point make(int t){return point{x+t*dx[d],y+t*dy[d],0};}
}p[MAXN],s[MAXN];
int find(int x)
{if(x^fa[x]) fa[x]=find(fa[x]);return fa[x];
}
int check(int x)
{int t=p[a].make(x)*p[b].make(x)-2*x;return t<=0?0:t;
}
void conquer(int l,int r)
{while(l<=r){int m=(l+r)/2;int m1=(l+m)/2,m2=(r+m)/2;int r1=check(m1),r2=check(m2);if(r1==0) res=min(res,m1);if(r2==0) res=min(res,m2);if(r1<=r2)r=m2-1;elsel=m1+1;}
}
signed main()
{n=read();for(int i=1;i<=n;i++){fa[i]=i;p[i]=point{read(),read(),read()};}for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){res=inf;a=i;b=j;conquer(0,2e9);g[i][j]=g[j][i]=res;}}memset(dis,0x3f,sizeof dis);dis[1]=0;for(int i=1;i<=n;i++){int id=0;for(int j=1;j<=n;j++)if(dis[id]>dis[j] && dis[j]!=-1)id=j;ans=max(ans,dis[id]);dis[id]=-1;for(int j=1;j<=n;j++)dis[j]=min(dis[j],g[id][j]);}if(ans==inf) puts("No solutions");else printf("%lld\n",ans);
}

2019.09.21 多校联合训练(普及组)相关推荐

  1. 2019.09.21 多校联合训练(提高组)

    东方记者 一.题目 [题目描述] 这一天,在幻想乡发生了N起大新闻,第i起大新闻发生在坐标(Xi,Yi)处.射命丸文从坐标(0,0)处出发,按照新闻发生的时间顺序前往各个新闻发生地收集资料,最后回到坐 ...

  2. 2019.09.15 多校联合训练(提高组)

    能量获取 一.题目 "封印大典启动,请出Nescafe魂珠!"随着圣主applepi一声令下,圣剑护法rainbow和魔杖护法freda将Nescafe魂珠放置于封印台上.封印台是 ...

  3. HDU 2019 Multi-University Training Contest 1 杭电2019多校联合训练赛 第一场 1001 Blank (6578)

    HDU 2019 Multi-University Training Contest 1 杭电2019暑期多校集训第一场 1001 Blank (6578) Problem Description T ...

  4. 2016多校联合训练1 B题Chess (博弈论 SG函数)

    题目大意:一个n(n<=1000)行,20列的棋盘上有一些棋子,两个人下棋,每回合可以把任意一个棋子向右移动到这一行的离这个棋子最近的空格上(注意这里不一定是移动最后一个棋子),不能移动到棋盘外 ...

  5. 2017 多校联合训练 3 题解

    Problem 1003 维护一个链表 链表中记录大于等于x的数 一开始链表中插入所有的数 从小到大枚举x 用双指针从左到右跳k次 做完一个x删除这个节点 1 #include<iostream ...

  6. 2018ACM暑期多校联合训练参(bao)赛(zha)记

    (这毁了我一个暑假的东西) 时间 2018-7-23至2018-8-22,一星期2场,共10场,每场5个小时. 题目链接(楼教主:"是男人就过八(116)题") 评分规则 单场得分 ...

  7. [HDU5788] Level Up [2016 Multi-University Training Contest 5 1008 (2016多校联合训练5)]

    题意 一棵树,每个节点有一个权值 Ai(Ai≤100000) A_i(A_i\le 100000),每个节点有另一个权值 Midi Mid_i,这个权值是以 i i为根子树中第⌈t2⌉\lceil \ ...

  8. 2017ACM暑期多校联合训练 - Team 7 1009 HDU 6128 Inverse of sum (数学计算)

    题目链接 Problem Description There are n nonnegative integers a1-n which are less than p. HazelFan wants ...

  9. 2018 多校联合训练 10

    Problem A Problem B Problem C Problem D Problem E 每个数的因子个数大概100个(最多128个) 那么把这些数全都放到集合里面就可以了. 然后直接上启发 ...

最新文章

  1. Loadrunner中的IP欺骗的设置以及误区
  2. AWS — AWS Direct Connect
  3. $.post请求的参数在后台代码中得到为null_996难得休息,小伙打开steam网页看了一款游戏,输入密码后却习惯性按了F12研究起了JS代码...
  4. Android 6种快速开发框架
  5. python取文本中间_Python读取两个字符串之间的特定文本行
  6. [vue-cli]vue-cli提供了的哪几种脚手架模板?
  7. update两个表中的同一字段的数据_用Python实现多个工作簿中的数据按列合并到同一个工作表中...
  8. 关于centos7下/etc/sysconfig/目录没有iptables问题
  9. 毕设-基于JavaWeb体育竞赛管理系统
  10. mysql修改数据库字段数值_mysql修改数据库字段的操作
  11. k8s实践(6)--Kubernetes安全:API Server访问控制
  12. tidb server的oom问题优化探索
  13. 水溶性花青素连接剂1617497-19-4,diSulfo-Cyanine5 alkyne,二磺酸花青素Cy5炔基
  14. 虚拟环境Vmware下改变Linux(CentOS7)IP地址
  15. 我工作上常用的--测试用例文档模板
  16. SIMD<SIMT<SMT: NVIDIA GPU的并行机制
  17. 开山斧0.3.8(跨平台版本)《源码已开放》
  18. 社会工程学攻击案例-伪装木马
  19. Android系统的定制
  20. CSS @font-face用法小结

热门文章

  1. Unity 游戏入门 四、 游戏地图的创建World Design – Tilemaps
  2. Linux驱动开发杂记(0x01) - 内核中的一些标记宏__init等
  3. android 布局管理器 各种布局简介
  4. AI 落后要挨打的苹果,5 年疯狂收购 25 家人工智能公司!
  5. 中国绝美情诗名句排行榜TOP100
  6. python段子_python 爬取 段子网 实例
  7. 阻止腾讯迷你首页弹出
  8. PHP数组操作程序,微信小程序学习数组操作
  9. js实现有效的括号--力扣
  10. 阿里妈妈API开发系列:item_link - 链接转换API返回说明