M-SOLUTIONS Programming Contest 2020 题解

题目质量好高啊,做完感觉好难涨智商了诶。(除了某一道程序又臭又长的F)

A - Kyu in AtCoder

我们可以放很多个if来判断,但这显然不美观。所以,可以观察到,每隔\(200\)点段位都减少\(1\),那么就可以直接通过算式算出了。

程序:

#include<bits/stdc++.h>
using namespace std; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); int x;
cin>>x;
cout<<10-x/200<<endl; return 0;
}

B - Magic 2

不管卡牌颜色,简单来说就是操作后$$A<B<C$$

并不用考虑这\(K\)次膜法如何分配,反向考虑,最少需要多少次操作使得$$A<B<C$$,这可以贪心的先操作\(B\)再操作\(C\)得到。

程序:

#include<bits/stdc++.h>
using namespace std; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); int a,b,c,k,n=0;
cin>>a>>b>>c>>k;
while(b<=a)b<<=1,n++;
while(c<=b)c<<=1,n++;
cout<<(n<=k?"Yes\n":"No\n"); return 0;
}

C - Marks

暴力的计算乘积,肯定要溢出的,所以我们来观察一下:(此处把第\(i\)天的等第简单地称作\(G_i\))

\[G_i = A_{i-k+1} \times A_{i-k+2} \times \dots \times A_{i-1} \times A_i
\]

那么,我们可以简单地看出:

\[G_i = G_{i-1} \times A_i \div A_{i-k}
\]

于是只要比较\(G_i\)和\(G_{i-1}\)只需要比较\(A_i\)和\(A_{i-k}\)就好了。程序:

#include<bits/stdc++.h>
using namespace std; int n,k;
int a[200005]; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
if(i>k){
cout<<(a[i]>a[i-k]?"Yes\n":"No\n");
}
} return 0;
}

D - Road to Millionaire

首先,低价买进,高价卖出,这点生意人的素养我们还是要有的。

我们看到,假设第\(A\)天买入\(C\)手,第\(B\)天卖出\(C\)手,可以转化为:第\(A\)天买入\(C\)手,第\(A+1\)天卖出\(C\)手,第\(A+1\)天买入\(C\)手,第\(A+2\)天卖出\(C\)手,……,第\(B-1\)天买入\(C\)手,第\(B\)天卖出\(C\)手。同时假如这当中有某一天,当天卖出翌日买入是亏损的,那么不买/卖肯定结果更好。

于是,贪心地比较今天和明天的价格并且作出买卖的操作即可获得正确答案。

程序虽然数组叫DP实际上还是贪心:

#include<bits/stdc++.h>
using namespace std; typedef long long ll; int n,a[85];
ll dp[85]; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
dp[1]=1000;
for(int i=1;i<n;i++){
dp[i+1]=max(dp[i],dp[i]/a[i]*a[i+1]+dp[i]%a[i]);
}
cout<<dp[n]<<endl; return 0;
}

E - M's Solution

首先,建立一条铁轨,虽然不一定要穿过居民区,但是,穿过一定能够获得最优结果。

(感性的)证明:假如铁轨不在居民区上,那么两侧的(走向这条铁轨的)居民数量一定相等,否则可以移动向居民数量更大的一边以获得更优结果,而且,假如两侧居民数量相等,那么任意移动铁轨也是可以的。

那么我们枚举要建立的铁轨就好喽。枚举可能的铁轨是\(O(3^N)\)的(对于每一个居民区,都有放东西向铁轨/南北向铁轨/不放铁轨三种做法),计算答案是\(O(N^2)\)的(可以通过二指针来达到\(O(N)\),但可以卡过去就不用了唷)。题目要求的限定铁轨数量,就在枚举的时候更新对应的答案即可。

程序:(记得考虑初始的两条铁轨)

#include<bits/stdc++.h>
using namespace std; typedef long long ll; int n,x[15],y[15],p[15],D[15],d[15];
ll ans[16]; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>n;
for(int i=0;i<n;i++)cin>>x[i]>>y[i]>>p[i];
memset(ans,0x3f,sizeof(ans));
ans[0]=0;
for(int i=0;i<n;i++){
D[i]=min(abs(x[i]),abs(y[i]));
ans[0]+=(ll)p[i]*D[i];
}
for(int s=0;s<1<<n;s++){
for(int t=s;t;t=(t-1)&s){
memcpy(d,D,sizeof(d));
for(int i=0;i<n;i++){
if(s>>i&1){
if(t>>i&1){
for(int j=0;j<n;j++){
d[j]=min(d[j],abs(x[i]-x[j]));
}
}else{
for(int j=0;j<n;j++){
d[j]=min(d[j],abs(y[i]-y[j]));
}
}
}
}
ll cur=0;
for(int i=0;i<n;i++){
cur+=(ll)d[i]*p[i];
}
ans[__builtin_popcount(s)]=min(ans[__builtin_popcount(s)],cur);
}
{
int t=0;
memcpy(d,D,sizeof(d));
for(int i=0;i<n;i++){
if(s>>i&1){
if(t>>i&1){
for(int j=0;j<n;j++){
d[j]=min(d[j],abs(x[i]-x[j]));
}
}else{
for(int j=0;j<n;j++){
d[j]=min(d[j],abs(y[i]-y[j]));
}
}
}
}
ll cur=0;
for(int i=0;i<n;i++){
cur+=(ll)d[i]*p[i];
}
ans[__builtin_popcount(s)]=min(ans[__builtin_popcount(s)],cur);
}
}
for(int i=0;i<=n;i++)cout<<ans[i]<<'\n'; return 0;
}

F - Air Safety

这道题考虑不太难,主要是实现恶心人。(AtCoder你变了!)

首先相撞的飞机大体有两种:

  1. 相向飞行的两架飞机,这个对于每一个横/纵坐标单独考虑就好。
  2. 飞行路线相互垂直的两架飞机,假如相撞,由于速度相等,它们到相撞的点的路程一定是相等的。你可以画出一个直角顶点是相撞点,其他两个顶点是飞机初始位置的等腰直角三角形来,就可以发现它们初始位置一定在同一条斜率为\(1\)或\(-1\)的直线上。那么记录这样的直线所过的向上/下飞行的飞机,再枚举左/右飞行的飞机并查找是否有经过它的直线就好。(先上下还是先左右没什么关系,就是咱喜欢的说)

程序:(还好,不需要离散化)

#include<bits/stdc++.h>
using namespace std; int n,X[200005],Y[200005];
char D[200005];
vector<pair<int,int>> RP,LP;
map<int,set<int>> RL,LL;
vector<int> LR[200005],RR[200005],UC[200005],DC[200005]; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>n;
for(int i=0;i<n;i++){
cin>>X[i]>>Y[i]>>D[i];
int &x=X[i],&y=Y[i];
char &d=D[i];
if(d=='U'){
UC[x].emplace_back(y);
LL[y-x].insert(y);
RL[x+y-1919810].insert(y);
}
if(d=='D'){
DC[x].emplace_back(y);
LL[x+y-1919810].insert(y);
RL[y-x].insert(y);
}
if(d=='R'){
RR[y].emplace_back(x);
RP.emplace_back(x,y);
}
if(d=='L'){
LR[y].emplace_back(x);
LP.emplace_back(x,y);
}
}
int ans=1e9;
for(int r=0;r<200000;r++){
sort(LR[r].begin(),LR[r].end());
LR[r].emplace_back(1919810);
sort(RR[r].begin(),RR[r].end());
for(int &x:RR[r]){
int y=*lower_bound(LR[r].begin(),LR[r].end(),x);
if(y!=1919810)ans=min(ans,(y-x)*5);
}
}
for(int c=0;c<200000;c++){
sort(UC[c].begin(),UC[c].end());
sort(DC[c].begin(),DC[c].end());
DC[c].emplace_back(1919810);
for(int &x:UC[c]){
int y=*lower_bound(DC[c].begin(),DC[c].end(),x);
if(y!=1919810)ans=min(ans,(y-x)*5);
}
}
for(pair<int,int> &px:RP){
int y;
if(RL.find(px.second-px.first)!=RL.end() && RL[px.second-px.first].lower_bound(px.second)!=RL[px.second-px.first].end()){
y=*RL[px.second-px.first].lower_bound(px.second);
ans=min(ans,(y-px.second)*10);
}
if(RL.find(px.second+px.first-1919810)!=RL.end() && RL[px.second+px.first-1919810].upper_bound(px.second)!=RL[px.second+px.first-1919810].begin()){
y=*(--RL[px.second+px.first-1919810].upper_bound(px.second));
ans=min(ans,(px.second-y)*10);
}
}
for(pair<int,int> &px:LP){
int y;
if(LL.find(px.second-px.first)!=LL.end() && LL[px.second-px.first].upper_bound(px.second)!=LL[px.second-px.first].begin()){
y=*(--LL[px.second-px.first].upper_bound(px.second));
ans=min(ans,(px.second-y)*10);
}
if(LL.find(px.second+px.first-1919810)!=LL.end() && LL[px.second+px.first-1919810].lower_bound(px.second)!=LL[px.second+px.first-1919810].end()){
y=*LL[px.second+px.first-1919810].lower_bound(px.second);
ans=min(ans,(y-px.second)*10);
}
}
if(ans==1e9)cout<<"SAFE";
else cout<<ans; return 0;
}

M-SOLUTIONS Programming Contest 2020 题解的更多相关文章

  1. atcoder Keyence Programming Contest 2020 题解

    比赛地址 A 题意:给一个\(n*m\)的初始为白色的矩阵,一次操作可以将一行或一列染成 黑色,问至少染出\(k\)个黑点的最少操作次数. \(n\),\(m\)<=100,\(k\)<= ...

  2. HHKB Programming Contest 2020 D - Squares 题解(思维)

    题目链接 题目大意 给你一个边长为n的正方形和边长为a和b的正方形,要求把边长为a和b的正方形放在长度为n的正方形内,且没有覆盖(可以相邻)求有多少种放法(mod 1e9+7) 题目思路 这个思路不是 ...

  3. Social Infrastructure Information Systems Division, Hitachi Programming Contest 2020 D题题解

    将题意转换为一开始\(t = 0\),第\(i\)个操作是令\(t \leftarrow (a_i + 1) t + (a_i + b_i + 1)\).记\(A_i = a_i + 1, B_i = ...

  4. Social Infrastructure Information Systems Division, Hitachi Programming Contest 2020 C题题解

    首先,我们将题目理解成若\(i\)与\(j\)距离恰好为\(3\),则不可能\(p_i \equiv p_j \equiv 1 \space or \space 2 (\bmod 3)\).这就相当于 ...

  5. 2021.7.27--Benelux Algorithm Programming Contest 2020 补提

    I Jigsaw 题目内容: 链接:https://ac.nowcoder.com/acm/contest/18454/I 来源:牛客网 You have found an old jigsaw pu ...

  6. HHKB Programming Contest 2020【ABCE】

    比赛链接:https://atcoder.jp/contests/hhkb2020/tasks A - Keyboard 代码 #include <bits/stdc++.h> using ...

  7. AtCoder AIsing Programming Contest 2020 D - Anything Goes to Zero (二进制,模拟)

    题意:给你一个长度为\(n\)的\(01\)串,从高位到低位遍历,对该位取反,用得到的十进制数\(mod\)所有位上\(1\)的个数,不断循环直到为\(0\),输出每次遍历时循环的次数. 题解:根据题 ...

  8. 【AtCoder】Dwango Programming Contest V题解

    A - Thumbnail 题意简述:给出N个数,找出N个数中和这N个数平均值绝对值最小的数 根据题意写代码即可= = #include <bits/stdc++.h> #define f ...

  9. Atcoder Panasonic Programming Contest 2020

    前三题随便写,D题是一道dfs的水题,但当时没有找到规律,直接卡到结束 A - Kth Term /  Time Limit: 2 sec / Memory Limit: 1024 MB Score ...

随机推荐

  1. Pycharm整体缩进和减少缩进

    整体缩进:鼠标拉选住代码块,按下tab键. 反向缩进:鼠标拉选住代码块,按下shift+tab键.

  2. 统计学习1:朴素贝叶斯模型(Numpy实现)

    模型 生成模型介绍 我们定义样本空间为\(\mathcal{X} \subseteq \mathbb{R}^n\),输出空间为\(\mathcal{Y} = \{c_1, c_2, ..., c_K\ ...

  3. 洛谷 P7516 - [省选联考 2021 A/B 卷] 图函数(Floyd)

    洛谷题面传送门 一道需要发现一些简单的性质的中档题(不过可能这道题放在省选 D1T3 中偏简单了?) u1s1 现在已经是 \(1\text{s}\)​ \(10^9\)​ 的时代了吗?落伍了落伍了/ ...

  4. 《python编程从入门到实践》读书实践笔记(一)

    本文是<python编程从入门到实践>读书实践笔记1~10章的内容,主要包含安装.基础类型.函数.类.文件读写及异常的内容. 1 起步 1.1 搭建环境 1.1.1 Python 版本选择 ...

  5. NECAT组装ONT long reads

    NECAT 可用于ONT数据的纠错,组装,如果想对ONT long reads进行call SV,也可以使用necatsv. githup网址:https://github.com/xiaochuan ...

  6. windows下的python安装pysam报错

    安装pysam时报错: 指定版本仍报错: 使用pysam-win安装: 但是import时不行: 貌似pysam在windows下难以正常配置,还是在Linux中用吧. https://www.jia ...

  7. 【ThermoRawFileParser】质谱raw格式转换mgf

    众所周知,Proteowizard MSconvert用于质谱原始数据的格式转换,但主要平台是windows,要想在Linux上运行需要打Docker或Wine,对于普通用户来说还是很困难的,想想质谱 ...

  8. leetcode刷题之数组NO.4

    1.题目 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原数 ...

  9. 日常Java 2021/11/6

    Java多线程编程 Java给多线程编程提供了内置的支持.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个钱程,每条线程并行执行不同的任务.多线程是多任务的一种特别的形式,但多线程使用 ...

  10. Hbase(二)【shell操作】

    目录 一.基础操作 1.进入shell命令行 2.帮助查看命令 二.命名空间操作 1.创建namespace 2.查看namespace 3.删除命名空间 三.表操作 1.查看所有表 2.创建表 3. ...