CF习题集二
CF习题集二
一、CF507E Breaking Good
题目描述
\(Breaking Good\)这个游戏对于有经验的玩家来说也有一定的难度。
游戏的主角小明希望加入一个叫斧头帮的犯罪团伙。这个团伙控制着整个国家\(n\)个城市间的\(m\)条双向道路,这些道路保证没有自环和重边,任何城市可以通过这些道路到达任何其他城市。
然而道路并不全都能通行,有些道路是需要修复。
现在这个团伙要搞一个大新闻!搞事地点位于城市\(1\)。像往常一样,这个行动最难的部分是搞事后如何逃到他们在城市n的总部。为了获得该团伙的信任,小明决定负责这项搞事行动,而且他提出了一个看起来很明智的计划。
首先,他们将在从城市1返回途中使用的路径总长度必须尽可能短;然后,为了让搞的大新闻更加刺激,他们必须炸毁所有不在这条路径上的其他道路。但是他们不必炸掉不能通行的道路。
如果选择的道路有一些不能通行的道路,他们将不得不在行动之前修复那些道路。
小明发现,有很多路径满足了条件\(1\)(即尽可能短),所以他决定在其中选择一条路径,使受影响道路的总数最小化。
你能帮助小明完成搞事并获得该团伙的信任吗?
分析
首先,我们要选择一条最短的路径
在路径最短的基础上,我们要尽量使受影响的道路数更少
因此我们要在跑\(Dij\)的结构体里存储三个东西
即当前节点的编号,当前节点距离起点的最短路径,当前路径下更改的道路条数
在进行松弛操作时,如果\(dis[u]>dis[now]+b[i].val\)
那么我们像之前那样更新\(dis\)值即可
如果\(dis[u]=dis[now]+b[i].val\)但是新的路径更改的道路条数更少
此时我们也需要更新
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int head[maxn],tot=1;
struct asd{
int from,to,next,val,jud;
}b[maxn];
void ad(int aa,int bb,int cc,int dd){
b[tot].from=aa;
b[tot].to=bb;
b[tot].next=head[aa];
b[tot].val=cc;
b[tot].jud=dd;
head[aa]=tot++;
}
struct jie{
int num,jl,hf;
jie(int aa,int bb,int cc){
num=aa,jl=bb,hf=cc;
}
bool operator < (const jie& A) const{
if(jl==A.jl) return hf>A.hf;
return jl>A.jl;
}
};
priority_queue<jie> q;
bool viss[maxn];
int dis[maxn],jl[maxn],hf[maxn];
void dij(){
memset(dis,0x3f,sizeof(dis));
memset(hf,0x3f,sizeof(hf));
dis[1]=0;
hf[1]=0;
q.push(jie(1,0,0));
while(!q.empty()){
int now=q.top().num;
int nhf=q.top().hf;
q.pop();
if(viss[now]) continue;
viss[now]=1;
for(int i=head[now];i!=-1;i=b[i].next){
int u=b[i].to;
if(dis[u]>dis[now]+b[i].val){
dis[u]=dis[now]+b[i].val;
jl[u]=i;
hf[u]=nhf+b[i].jud;
q.push(jie(u,dis[u],hf[u]));
} else if(dis[u]==dis[now]+b[i].val){
if(hf[u]>nhf+b[i].jud){
jl[u]=i;
hf[u]=nhf+b[i].jud;
q.push(jie(u,dis[u],hf[u]));
}
}
}
}
}
vector<int> g;
bool vis[maxn];
int main(){
memset(head,-1,sizeof(head));
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int aa,bb,cc;
scanf("%d%d%d",&aa,&bb,&cc);
ad(aa,bb,1,cc^1);
ad(bb,aa,1,cc^1);
}
dij();
int ans=0;
int now=n;
while(jl[now]){
if(jl[now]%2==0) g.push_back(jl[now]-1);
else g.push_back(jl[now]);
now=b[jl[now]].from;
}
for(int i=0;i<g.size();i++){
vis[g[i]]=1;
}
for(int i=1;i<tot;i+=2){
if(vis[i]){
if(b[i].jud==1){
ans++;
}
} else {
if(b[i].jud==0){
ans++;
}
}
}
printf("%d\n",ans);
for(int i=1;i<tot;i+=2){
if(vis[i]){
if(b[i].jud==1){
printf("%d %d %d\n",b[i].from,b[i].to,1);
}
} else {
if(b[i].jud==0){
ans++;
printf("%d %d %d\n",b[i].from,b[i].to,0);
}
}
}
return 0;
}
二、CF467C George and Job
题目描述
新款手机 \(iTone6\) 近期上市,\(George\) 很想买一只。不幸地,\(George\) 没有足够的钱,所以 \(George\) 打算当一名程序猿去打工。现在\(George\)遇到了一个问题。 给出一组有 \(n\) 个整数的数列\(p_1,p_2,...,p_n\),你需要挑出 \(k\) 组长度为 \(m\) 的数,要求这些数互不重叠 即$ [l_{1},r_{1}],[l_{2},r_{2}],...,[l_{k},r_{k}] (1<=l_{1}<=r_{1}<l_{2}<=r_{2}<...<l_{k}<=r_{k}<=n;r_{i}-l_{i}+1=m)[l1,r1],[l2,r2],...,[lk,rk]$
使选出的数的和值最大,请你帮助George码出这份代码
分析
我们设\(f[i][j]\)为前\(i\)个数选出了\(j\)组,其中第\(i\)个数必须选的最大值
那么我们就可以写出如下的状态转移方程
f[i][k]=max(f[i][k],f[j][k-1]+sum[i]-sum[i-m]);
时间复杂度为\(O(n^3)\)
实际上,我们可以用单调队列对于每一个\(i\)维护\(f[j][k-1]\)的最大值
这样时间复杂度就降到了\(O(n^2)\)
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e3+5;
#define int long long
int sum[maxn],a[maxn],f[maxn][maxn],q[maxn],head,tail;
signed main(){
int n,m,p;
scanf("%lld%lld%lld",&n,&m,&p);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
}
int ans=0;
for(int j=1;j<=p;j++){
head=1,tail=1;
memset(q,0,sizeof(q));
for(int i=m;i<=n;i++){
if(head<=tail)f[i][j]=max(f[i][j],f[q[head]][j-1]+sum[i]-sum[i-m]);
while(head<=tail && f[i-m+1][j-1]>f[q[tail]][j-1]) tail--;
q[++tail]=i-m+1;
ans=max(ans,f[i][p]);
}
}
printf("%lld\n",ans);
return 0;
}
三、CF333E Summer Earnings
题目描述
在一个平面内给出\(n\)个点的坐标,任选其中三个为圆心作半径相同的圆,要求这三个圆不能相交但可以相切,求能画出的圆中的最大半径。
分析
对于平面上的三个点,我们可以将其分为两种情况
一种情况是三个点都位于一条直线上
此时我们的最大直径只能是三点当中距离最小的两点的距离
还有一种情况是三个点不在同一条直线上
此时我们的最大直径也只能是三点当中距离最小的两点的距离
因为我们要保证圆只能相切,不能相交
如果直径再大一点,势必会出现相交的情况
所以我们可以先预处理出任意两点间的距离,然后按距离从小到大排好序
每次取出两个点,我们就判断一下它们是否和同一个点已经连到一起
如果已经连到一起,我们就输出当前答案,否则继续寻找
而判断两个点是否和同一个点连到一个我们可以用\(bitset\)解决
代码
#include<bits/stdc++.h>
using namespace std;
typedef double dd;
const int maxn=3005;
dd jlx[maxn],jly[maxn];
bitset<maxn> g[maxn];
struct asd{
int from,to;
dd da;
}b[maxn*maxn];
dd solve(int aa,int bb){
return (dd)sqrt((jlx[aa]-jlx[bb])*(jlx[aa]-jlx[bb])+(jly[aa]-jly[bb])*(jly[aa]-jly[bb]));
}
bool cmp(asd aa,asd bb){
return aa.da>bb.da;
}
int main(){
int n,cnt=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lf%lf",&jlx[i],&jly[i]);
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(i==j) continue;
b[++cnt].da=solve(i,j);
b[cnt].from=i;
b[cnt].to=j;
}
}
sort(b+1,b+1+cnt,cmp);
for(int i=1;i<=cnt;i++){
int aa=b[i].from,bb=b[i].to;
g[aa][bb]=1,g[bb][aa]=1;
if((g[aa] & g[bb]).count()){
printf("%.20lf\n",b[i].da/2.0);
exit(0);
}
}
return 0;
}
四、CF132C Logo Turtle
题目描述
很多人把\(LOGO\)编程语言和海龟图形联系起来。在这种情况下,海龟沿着直线移动,接受命令“T”(“转向180度”)和“F”(“向前移动1单元”)。
你会收到一份给海龟的命令清单。你必须从列表中精确地改变N个命令(一个命令可以被改变多次)。要求出海龟在遵循修改后的所有命令后,会从起点最远可以移到多远?
分析
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
char s[maxn];
int f[maxn][maxn][3],wz[maxn];
int main(){
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++){
f[i][j][1]=f[i][j][0]=-0x3f3f3f3f;
}
}
scanf("%s",s+1);
int n;
scanf("%d",&n);
int len=strlen(s+1);
f[0][0][0]=0;
f[0][0][1]=0;
for(int i=1;i<=len;i++){
for(int j=0;j<=n;j++){
for(int k=0;k<=j;k++){
if(s[i]=='F'){
if(k&1){
f[i][j][0]=max(f[i][j][0],f[i-1][j-k][1]);
f[i][j][1]=max(f[i][j][1],f[i-1][j-k][0]);
} else {
f[i][j][0]=max(f[i][j][0],f[i-1][j-k][0]+1);
f[i][j][1]=max(f[i][j][1],f[i-1][j-k][1]-1);
}
} else {
if(k&1){
f[i][j][0]=max(f[i][j][0],f[i-1][j-k][0]+1);
f[i][j][1]=max(f[i][j][1],f[i-1][j-k][1]-1);
} else {
f[i][j][0]=max(f[i][j][0],f[i-1][j-k][1]);
f[i][j][1]=max(f[i][j][1],f[i-1][j-k][0]);
}
}
}
}
}
printf("%d\n",max(f[len][n][0],f[len][n][1]));
return 0;
}
CF习题集二的更多相关文章
- CF习题集一
CF习题集一 一.CF915E Physical Education Lessons 题目描述 \(Alex\)高中毕业了,他现在是大学新生.虽然他学习编程,但他还是要上体育课,这对他来说完全是一个意 ...
- CF习题集三
CF习题集三 一.CF8C Looking for Order 题目描述 \(Lena\)喜欢秩序井然的生活.一天,她要去上大学了.突然,她发现整个房间乱糟糟的--她的手提包里的物品都散落在了地上.她 ...
- 《Java练习题》习题集二
编程合集: https://www.cnblogs.com/jssj/p/12002760.html Java总结:https://www.cnblogs.com/jssj/p/11146205.ht ...
- Unity3D编程学习分享
学习地址:http://www.ixueyun.com/lessons/detail-lessonId-692.html 一.课程概述: 以前大部分3D游戏出现在pc和ps.XBox等专业游戏主机上, ...
- 【一天一道LeetCode】#17. Letter Combinations of a Phone Number
一天一道LeetCode (一)题目 Given a digit string, return all possible letter combinations that the number cou ...
- Javassist 字节码 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Zookeeper 系列(五)Curator API
Zookeeper 系列(五)Curator API 一.Curator 使用 Curator 框架中使用链式编程风格,易读性更强,使用工程方法创建连接对象使用. (1) CuratorFramewo ...
- shell工具使用配置备忘
一.bash之vi mode.两种方式:set -o vi(只让bash自己进入vi模式)或 set editing-mode vi(让所有使用readline库函数的程序在读取命令行时都进入vi模式 ...
- 《Java练习题》Java编程题合集(全)
前言:不仅仅要实现,更要提升性能,精益求精,用尽量少的时间复杂度和空间复杂度解决问题. 初学者: <Java练习题>习题集一 https://www.cnblogs.com/jssj/ ...
随机推荐
- day78 作业
目录 1 在作业.html的代码基础上,完成商品数量的加减,注意商品数量如果低于0个,则自动删除当前商品 2 在作业.html的代码基础仧,完成购物车总价格的计算 3 使用ajax获取北京天气,并把昨 ...
- 【XCTF】ics-04
信息: 题目来源:XCTF 4th-CyberEarth 标签:PHP.SQL注入 题目描述:工控云管理系统新添加的登录和注册页面存在漏洞,请找出flag 解题过程 进入注册页面,尝试注册: 进行登录 ...
- python数据处理(四)之数据获取与存储
1.前烟 几个数据问题 1.1 是否能够联系上作者本人 1.2 数据是否定期检查错误并更新 1.3 数据是否包含数据获取方法的信息,是否包含数据获取过程中使用的样本类型 1.4 有没有其他数据源可以验 ...
- python并发编程02 /多进程、进程的创建、进程PID、join方法、进程对象属性、守护进程
python并发编程02 /多进程.进程的创建.进程PID.join方法.进程对象属性.守护进程 目录 python并发编程02 /多进程.进程的创建.进程PID.join方法.进程对象属性.守护进程 ...
- 绘图和可视化知识图谱-《利用Python进行数据分析》
所有内容整理自<利用Python进行数据分析>,使用MindMaster Pro 7.3制作,emmx格式,源文件已经上传Github,需要的同学转左上角自行下载或者右击保存图片. 其他章 ...
- Java多线程原理+基础知识(超级超级详细)+(并发与并行)+(进程与线程)1
Java多线程 我们先来了解两个概念!!!! 1.什么是并发与并行 2.什么是进程与线程 1.什么是并发与并行 1.1并行:两个事情在同一时刻发生 1.2并发:两个事情在同一时间段内发生 并发与并行的 ...
- P2060 马步距离(洛谷)
我们无论遇到什么困难,都不要拖,微笑着面对他,战胜拖延的最好方法就是面对拖延. 今天又拖延了…… 早晨听完老师讲课,本想做一道题练练手的,结果因为懒,瘫了一上午.最后在固定的刷题时间去面对了这道题,然 ...
- 获取字符串指定字符的第n次出现位置
create function uf_findx (@text nvarchar(max),@find_x varchar(200),@find_n int)returns intasbegin -- ...
- 小书MybatisPlus第6篇-主键生成策略精讲
本文为mybatis系列文档的第6篇,前5篇请访问下面的网址. 小书MybatisPlus第1篇-整合SpringBoot快速开始增删改查 小书MybatisPlus第2篇-条件构造器的应用及总结 小 ...
- 【Unity3D】简单常用的功能实现1——鼠标点击实现移动
[鼠标点击实现移动] 第一步,在要移动的GameObject的Inspector面板中添加角色控制器组件并调整参数. 参数的调整可以依照Scene面板,如下图的绿色线框(角色控制器组件是一种胶囊形状的 ...