M-SOLUTIONS Programming Contest 2021(AtCoder Beginner Contest 232) 题解
因为偷懒就只写G和H的题解了。
G - Modulo Shortest Path
首先可以观察到对于一条从点\(i\)到点\(j\)的边,权值只有两种:\(A_i+B_j\)和\(A_i+B_j-M\)。
那么我们假如把点按照\(B\)升序排成一列,那么当中的一个点肯定只会向前半部分连权值为\(A_i+B_j\)的边,后半部分连权值\(A_i+B_j-M\)的边。
我们可以把一个点拆成入点和出点(此时仍旧按照\(B\)升序排成两列),由出点向入点连权值为\(A_i+B_j\)和\(A_i+B_j-M\)的这两种边,入点向对应出点连接权值为\(0\)的边。
虽然此时边数仍旧是\(O(N^2)\)的,但是我们可以在每一个入点向下一个入点连一条权值为它们的\(B_i\)的差值的边,可以看成是一种反悔操作,走到入点了可以不走向出点,而是往下一个入点继续走,再走到对应的出点。这样发现没有必要给每一个点的出点连那么多条边出去了,只需要两条,一条连向序列开头的点,一条连向第一个使得权值和大于等于\(M\)的点。那么每一条原来的出点向入点连接的边都可以看成是一条现在出点向入点连接的边和一条入点构成的链的组合。
接下来只需要从起点到终点跑最短路就行了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,S,T;
pair<pair<int,int>,int> a[200005];
vector<pair<int,int>> g[400005];
ll d[400005];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i].first.first;
for(int i=1;i<=n;i++)cin>>a[i].first.second,a[i].second=i;
sort(a+1,a+1+n,[](const pair<pair<int,int>,int> &a,const pair<pair<int,int>,int> &b){
if(a.first.second!=b.first.second)return a.first.second<b.first.second;
return a.second<b.second;
});
S=1;
while(a[S].second!=1)S++;
T=1;
while(a[T].second!=n)T++;
for(int i=1;i<n;i++){
g[n+i].emplace_back(n+i+1,a[i+1].first.second-a[i].first.second);
}
for(int i=1;i<=n;i++){
g[n+i].emplace_back(i,0);
g[i].emplace_back(n+1,a[i].first.first+a[1].first.second);
int l=1,r=n,mid,res=-1;
while(l<=r){
mid=l+r>>1;
if(a[i].first.first+a[mid].first.second>=m){
res=mid;
r=mid-1;
}else{
l=mid+1;
}
}
if(res!=-1)g[i].emplace_back(n+res,a[i].first.first+a[res].first.second-m);
}
priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<pair<ll,int>>> q;
q.emplace(0,S);
memset(d,0x3f,sizeof(d));
d[S]=0;
while(!q.empty()){
ll cd;
int x;
tie(cd,x)=q.top();
q.pop();
if(cd>d[x])continue;
for(auto &[y,z]:g[x])if(d[y]>cd+z){
q.emplace(d[y]=cd+z,y);
}
}
cout<<d[T]<<'\n';
return 0;
}
H - King's Tour
比赛时没有想到递归处理的我真是铸币呜呜呜
首先可以考虑只有两行或者只有两列的棋盘怎么处理,那么由于八向移动的特性可以这么处理(起点在左上角,红点为终点):

然后就考虑行数和列数都至少为\(3\)的情况(同样默认起点左上角),尝试走过最上方的一行,或者最左边的一列,由于终点一定不会在左上角,且行数和列数都大于\(2\),那么一定两种操作可以选做一种,并且做完以后剩下来没访问过的棋盘仍旧是满足起点在一个角上且终点不和起点相同位置。
然后递归处理即可。
#include<bits/stdc++.h>
using namespace std;
vector<pair<int,int>> sol(int n,int m,int a,int b){
vector<pair<int,int>> r;
if(m==2){
for(int i=1;i<a;i++){
r.emplace_back(i,1);
r.emplace_back(i,2);
}
for(int i=a;i<=n;i++)r.emplace_back(i,b^3);
for(int i=n;i>=a;i--)r.emplace_back(i,b);
}else if(n>2&&(a>2||a==2&&b!=m)){
for(int i=1;i<=m;i++)r.emplace_back(1,i);
for(auto &[x,y]:sol(n-1,m,a-1,m+1-b))r.emplace_back(x+1,m+1-y);
}else{
r=sol(m,n,b,a);
for(auto &[x,y]:r)swap(x,y);
}
return r;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m,a,b;
cin>>n>>m>>a>>b;
for(auto &[x,y]:sol(n,m,a,b))cout<<x<<' '<<y<<'\n';
return 0;
}
M-SOLUTIONS Programming Contest 2021(AtCoder Beginner Contest 232) 题解的更多相关文章
- AtCoder Beginner Contest 076
A - Rating Goal Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Takaha ...
- atcoder beginner contest 251(D-E)
Tasks - Panasonic Programming Contest 2022(AtCoder Beginner Contest 251)\ D - At Most 3 (Contestant ...
- AtCoder Beginner Contest 100 2018/06/16
A - Happy Birthday! Time limit : 2sec / Memory limit : 1000MB Score: 100 points Problem Statement E8 ...
- KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解
KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解 哦淦我已经菜到被ABC吊打了. A - Century 首先把当前年 ...
- AtCoder Beginner Contest 184 题解
AtCoder Beginner Contest 184 题解 目录 AtCoder Beginner Contest 184 题解 A - Determinant B - Quizzes C - S ...
- AtCoder Beginner Contest 255(E-F)
Aising Programming Contest 2022(AtCoder Beginner Contest 255) - AtCoder E - Lucky Numbers 题意: 给两个数组a ...
- AtCoder Beginner Contest 052
没看到Beginner,然后就做啊做,发现A,B太简单了...然后想想做完算了..没想到C卡了一下,然后还是做出来了.D的话瞎想了一下,然后感觉也没问题.假装all kill.2333 AtCoder ...
- AtCoder Beginner Contest 053 ABCD题
A - ABC/ARC Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Smeke has ...
- AtCoder Beginner Contest 136
AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...
随机推荐
- 一文详解MySQL的锁机制
一.表级锁.行级锁.页级锁 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则. MySQL数据库由于其自身架构的特点,存在多种数据存储引擎, ...
- 『学了就忘』Linux软件包管理 — 49、拓展:Linux中通过脚本安装程序
目录 1.脚本程序简介 2.Webmin安装 (1)简介 (2)安装 (3)使用 1.脚本程序简介 脚本程序包并不多见,所以在软件包分类中并没有把它列为一类.它更加类似于Windows下的程序安装,有 ...
- git不显示提交代码
今天提交代码找不到提交的具体代码,找了好半天,最后发现是右边能下拉能拉下去,尴尬.
- jpa生成uuid
使用jpa可以生成uuid,但是我直接添加数据没有id值会报错,只在程序中有效,如果直接修改数据库需要手动填写,另外长度不要乱填 ,之前填了200,找了半天才找到原因. package com.jav ...
- 多线程07.thread-join
package com.wangwenjun.concurrency.chapter5; public class ThreadJoin3 { public static void main(Stri ...
- Kubernetes Pod 全面知识
Pod 是在 Kubernetes 中创建和管理的.最小的可部署的计算单元,是最重要的对象之一.一个 Pod 中包含一个或多个容器,这些容器在 Pod 中能够共享网络.存储等环境. 学习 Kubern ...
- Identity Server 4 从入门到落地(一)—— 从IdentityServer4.Admin开始
最近项目中需要使用Identity Server 4,以前对这个技术只是有些了解,没有系统研究过,网上相关的资料不少,大多是从编写一个简单的认证服务开始,离能够落地使用有相当的距离,理论学习如何不结合 ...
- Web Api 宿主的搭建
首先我们要清楚一个概念,宿主.宿主是什么意思?先从了解一下Hosting开始吧! 有关Hosting的基础知识 Hosting是一个非常重要,但又很难翻译成中文的概念.翻译成:寄宿,大概能勉强地传达它 ...
- 洛谷 P6144 - [USACO20FEB]Help Yourself P(二项式定理+线段树)
题面传送门 题意: 给定 \(n\) 条线段,第 \(i\) 条线段左右端点分别为 \(l_i,r_i\) 定义一个线段集合的复杂度为其形成的连通块的个数的 \(k\) 次方. 求这 \(n\) 条线 ...
- 巩固javaweb的第二十八天
巩固内容: 设置页面的编码方式 实现代码: 每个 JSP 页面都需要设置编码方式,设置 JSP 页面的编码方式可以是下面两种方式 之一. 方式一: <%@ page contentType=&q ...