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. [loj3277]星座3

    如果不合法,利用贪心发现当且仅当某两个星星所构成的矩形中没有白点 反过来,考虑留下若干个星星,那么即要求留下的星星两两之间满足:$\max_{x_{1}\le i\le x_{2}}a_{i}\ge ...

  2. 洛谷 P6772 - [NOI2020]美食家(广义矩阵快速幂)

    题面传送门 题意: 有一张 \(n\) 个点 \(m\) 条边的有向图,第 \(0\) 天的时候你在 \(1\) 号城市,第 \(T\) 天的时候你要回到 \(1\) 号城市. 每条边上的边权表示从城 ...

  3. Codeforces 436D - Pudding Monsters(dp)

    Codeforces 题目传送门 & 洛谷题目传送门 u1s1 这题数据范围有点迷惑啊--乍一看 \(\mathcal O(nm)\) 过不去,还以为是正解是 \(\mathcal O(n+m ...

  4. 【机器学习与R语言】10- 关联规则

    目录 1.理解关联规则 1)基本认识 2)Apriori算法 2.关联规则应用示例 1)收集数据 2)探索和准备数据 3)训练模型 4)评估性能 5)提高模型性能 1.理解关联规则 1)基本认识 购物 ...

  5. C语言 文本字符串存入二维数组

    字符串存入数组 文本内容: line1_1 line1_2line2_1 line2_2line3_1 line3_2line4_1 line4_2line5_1 line5_2line6_1 lin ...

  6. jenkins原理简析

    持续集成Continuous Integration(CI) 原理图: Gitlab作为git server.Gitlab的功能和Github差不多,但是是开源的,可以用来搭建私有git server ...

  7. Linux服务器I/O性能分析-1

    一.IOSTAT误区 1.1 误区-svctm Linux上的svctm是重要的I/O指标(I/O平均服务时间-单位毫秒),这个值直接反映了硬件的性能(I/O请求从SCSI层发出--->I/O完 ...

  8. 通过yum安装 memcache

    . 通过yum安装 复制代码代码如下: yum -y install memcached#安装完成后执行:memcached -h#出现memcached帮助信息说明安装成功 2. 加入启动服务 复制 ...

  9. (转载)Java里新建数组及ArrayList java不允许泛型数组

    java中新建数组: String[] s;//定义的时候不需要设置大小 s = new String[5];//为数组分配空间时就要设置大小   对于ArrayList, ArrayList< ...

  10. day35前端基础之BOM和DOM

    day35前端基础之BOM和DOM BOM操作 简介 BOM(Browser Object Model)是指浏览器对象模型,它使 JavaScript 有能力与浏览器进行"对话". ...