当前位置: 首页 > news >正文

Codeforces EDU Round 179 A~D

多测不清空,爆零两行泪。

A - Energy Crystals

题意

有三个整数 a 1 a_1 a1 a 2 a_2 a2 a 3 a_3 a3,可以将其中一个数改为任意正整数,但是必须满足对于任意两个 i i i j ( 1 ≤ i , j ≤ 3 ) j(1\le i,j\le3) j(1i,j3),有:
a i ≥ ⌊ a j 2 ⌋ a_i\ge\lfloor\frac{a_j}{2}\rfloor ai2aj
求对这三个数最少操作多少次使得三个数都变成 n n n

分析

先来枚举一下对于第 i i i次操作最大能达到多少。

imax
11
21
33
⋯ \cdots ⋯ \cdots
2 n 2n 2n 2 n − 1 2^{n}-1 2n1
2 n + 1 2n+1 2n+1 2 n − 1 2^{n}-1 2n1

(后面两组找规律可得)
对于两个整数 a a a b b b,且 a < b a<b a<b,如果在第 i i i次可以达到 b b b,那么也能达到 a a a
所以,思路就是找一个正整数 p p p,使得 2 p − 1 ≤ n 2^p-1\le n 2p1n,最后的答案就是 2 n + 1 2n+1 2n+1

#include<bits/stdc++.h>
#define int long long
#define endl putchar('\n')
using namespace std;
int read(){int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();return x*f;
}
void print(int x){if(x<0)putchar('-'),x=-x;if(x<10){putchar(x+'0');return;}print(x/10);putchar(x%10+'0');
}
int T;
signed main(){T=read();while(T--){int x=read();int ans=1,i;for(i=1;i<=64;i++){ans=ans*2;if(ans>x)break;}print(i*2+1);endl;}
}

B - Fibonacci Cubes

题意

n n n个正方体,第 i i i个正方体的棱长为 f i f_i fi,对于 f i f_i fi,有:
f 1 = 1 f 2 = 2 f i = f i − 1 + f i − 2 ( f > 2 ) f_1=1\\ f_2=2\\ f_i=f_{i-1}+f_{i-2}(f>2) f1=1f2=2fi=fi1+fi2(f>2)
m m m个盒子,第 i i i个盒子的长宽高分别为 w i w_i wi h i h_i hi l i l_i li
立方体摆放需遵循以下规则:

  • 立方体必须与盒子边平行放置;
  • 每个立方体必须直接放置在盒底,或叠放在其他立方体上且下方空间必须被完全填满;
  • 较大的立方体不能叠放在较小立方体上。

问这些盒子分别能不能按要求装下所有正方体。

分析

由于 n n n个盒子的棱长分别是斐波拉切数列的前 n n n位,所以可以考虑下图:(正方形表示正方体的俯视图,正方形内数字表示正方体的棱长)。


可以发现,对于第 n n n个正方体,只要其上还剩下 f n − 1 f_{n-1} fn1高度的盒子空间,那么就能放下第 n − 1 n-1 n1个正方体,对于第 n − 1 n-1 n1个正方体以此类推……
最后可以证明,只要能放下第 n n n个和第 n − 1 n-1 n1个正方体,就能放下所有的正方体。

#include<bits/stdc++.h>
#define endl putchar('\n')
using namespace std;
const int N=1e6+5;
int read(){int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();return x*f;
}
void putstr(string s){for(int i=0;i<s.size();i++)putchar(s[i]);
}
int n,m;
int T;
int w[N],h[N],l[N];
int f[N]={1,1};
signed main(){T=read();for(int i=2;i<=10;i++)f[i]=f[i-1]+f[i-2];while(T--){n=read(),m=read();for(int i=1;i<=m;i++)w[i]=read(),h[i]=read(),l[i]=read();string p="";for(int i=1;i<=m;i++){if(f[n]>w[i]||f[n]>h[i]||f[n]>l[i]){//检查第n个正方体p.push_back('0');continue;}int x=w[i]-f[n],y=h[i]-f[n],z=l[i]-f[n];if(f[n-1]>x&&f[n-1]>y&&f[n-1]>z){//检查第n-1个正方体p.push_back('0');continue;}p.push_back('1');}putstr(p);endl;}
}

C - Equal Values

题意

n n n个整数 a 1 a_1 a1 a 2 a_2 a2 a 3 … a n a_3\ldots a_n a3an,可以进行两种操作:

  • 选择位置 i i i,将 a 1 … i − 1 a_{1\ldots i-1} a1i1全部变成 a i a_i ai,代价为 ( i − 1 ) ⋅ a i (i-1)\cdot a_i (i1)ai
  • 选择位置 i i i,将 a i + 1 … n a_{i+1\ldots n} ai+1n全部变成 a i a_i ai,代价为 ( n − i ) ⋅ a i (n-i)\cdot a_i (ni)ai
    求将 n n n个整数全部变成一样的最小代价。

分析

举例两个情况
情况1
5 2 2 5 2 2 5\\2\ 2\ 5\ 2\ 2 52 2 5 2 2
这个时候选择 a 2 a_2 a2向右边变化,代价为 6 6 6,虽然说右边只有 5 5 5这个不同的数字,但是还是得将 5 2 2 5\ 2\ 2 5 2 2三个数全部变化。
可以得出,当两部分相同的数没有相连的时候,互相没有任何影响。
情况2
8 5 4 2 2 2 2 2 1 8\\5\ 4\ 2\ 2\ 2\ 2\ 2\ 1 85 4 2 2 2 2 2 1
有一种方案是选择 a 8 a_8 a8向左边变化,代价为 7 7 7,但明显不是最优的。可选择 a 3 a_3 a3向左变化 a 7 a_7 a7向右变化,代价为 6 6 6,中间由于都是 2 2 2就不用变了。
可以得出,对于相邻数,互相是有影响的,变化时只用取两端的数左右变化就行了。

可以先求出每一个点对应联通块的左右端点,然后记录最小值就行了。

#include<bits/stdc++.h>
#define int long long
#define endl putchar('\n')
using namespace std;
const int N=1e6+5;
int read(){int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();return x*f;
}
void print(int x){if(x<0)putchar('-'),x=-x;if(x<10){putchar(x+'0');return;}print(x/10);putchar(x%10+'0');
}
int n;
int T;
int a[N];
int f[N];
int k[N];
signed main(){T=read();while(T--){n=read();for(int i=1;i<=n;i++)a[i]=read(),f[i]=i,k[i]=i;for(int i=2;i<=n;i++){if(a[i]==a[i-1])f[i]=f[i-1];}for(int i=n-1;i>=1;i--){if(a[i]==a[i+1])k[i]=k[i+1];}int mn=1e18;for(int i=1;i<=n;i++){mn=min(mn,(f[i]-1)*a[i]+(n-k[i])*a[i]);}print(mn);endl;}
}

D - Creating a Schedule

题意

n n n个班级和 m m m间教室,教室编号为一个至少三位的数,出去最后两位剩下的表示教室所在的楼层。
n n n个班级每天都有 6 6 6节课,且每个班级的第 k k k节课在同一时间进行,两个班级不能同时在同一件教室上课。
请你设计一个课程表,使每个班级学生上下楼移动的距离最大。

分析

先考虑两个班级的情况。
当只有两个班级的时候,可以考虑让两个班级在最高层的最底层之间交替上课,可以实现移动最大化。
当出现第三个班级的时候,可以考虑让其在次大层和次小层移动,获得最大收益。
第四层同理。
以此类推。

相关文章:

  • 仿真每日一练 | ABAQUS连接单元的应用——螺栓预紧力
  • 关于Web安全:8. Web 攻击流量分析与自动化
  • 学习笔记(26):线性代数-张量的降维求和,简单示例
  • Halcon透视矩阵
  • 学习笔记(25):线性代数,矩阵-矩阵乘法原理
  • 【Android】Android Studio项目代码异常错乱问题处理(2020.3版本)
  • AOSP (Android11) 集成Google GMS三件套
  • 服务器信任质询
  • Ubuntu Cursor升级成v1.0
  • 黑龙江云前沿服务器租用:便捷高效的灵活之选​
  • Linux容器篇、第二章_01Ubuntu22 环境下 KubeSphere 容器平台高可用搭建全流程
  • 矩阵和向量范数的区别分析
  • 【案例分享】如何借助JS UI组件库DHTMLX Suite构建高效物联网IIoT平台
  • Opencv中的copyto函数
  • Keil调试模式下,排查程序崩溃简述
  • 【行驶证识别成表格】批量OCR行驶证识别与Excel自动化处理系统,行驶证扫描件和照片图片识别后保存为Excel表格,基于QT和华为ocr识别的实现教程
  • MCP(Model Context Protocol)AI大模型的超级外挂
  • 安装pytorch、cuda11.8
  • 攻击模型的恶意行为检测
  • 全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
  • 微网站的好处/如何将网站的关键词排名优化
  • 佛山知名网站建设公司/哪个浏览器看黄页最快夸克浏览器
  • 软件开发外包公司靠谱吗/肇庆seo按天计费
  • 免费商城建站平台/深圳网络推广大师
  • 成都网站快照优化公司/stp营销战略
  • 2015年做那个网站能致富/免费推广网站推荐