Codeforces Round #485 (Div. 2)
传送门:
https://codeforces.com/contest/987
A
模拟,开个 map
。
int main(){
map<char, string> w;
w['p']="Power", w['g']="Time", w['b']="Space", w['o']="Soul", w['r']="Reality", w['y']="Mind";
int n; cin>>n;
while(n--){
string s; cin>>s;
char ch=s[0];
w.erase(ch);
}
cout<<w.size()<<endl;
for(auto [x, y]: w) cout<<y<<endl;
return 0;
}
B
简单的高中数学。
取个 ,发现原式等价于 (此时 ,相应地需要对此特判)。
设 ,对 求导可以发现:在 的时候函数是单调增的,那么在 的时候我们直接对 的大小进行判断即可。
在 的时候直接计算。
int main(){
int x, y; cin>>x>>y;
if(x==1){
if(y==1) putchar('=');
else putchar('<');
return 0;
}
if(y==1){
if(x==1) putchar('=');
else putchar('>');
return 0;
}
if(x<5 && y<5){
int a=pw(x, y), b=pw(y, x);
if(a>b) putchar('>');
else if(a==b) putchar('=');
else putchar('<');
return 0;
}
int a=x, b=y;
if(a>b) putchar('<');
else if(a==b) putchar('=');
else putchar('>');
return 0;
}
C
的范围支持 ,因此考虑枚举两维 ,然后求位置 的贡献,这个贡献可以通过预处理信息:位置 之后满足 的位置的 的最小值 来求出。
// Problem: C. Three displays
// Contest: Codeforces - Codeforces Round #485 (Div. 2)
// URL: https://codeforces.com/contest/987/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define x first
#define y second
using pii = pair<int, int>;
using ll = long long;
inline void read(int &x){
int s=0; x=1;
char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=3030;
int s[N], c[N], n;
int g[N];
int main(){
cin>>n;
rep(i,1,n) read(s[i]);
rep(i,1,n) read(c[i]);
rep(i,1,n){
g[i]=1e9;
rep(j,i+1,n) if(s[j]>s[i]) g[i]=min(g[i], c[j]);
}
int res=1e9;
rep(i,1,n){
rep(j,i+1,n) if(s[j]>s[i]){
int t=c[i]+c[j]+g[j];
res=min(res, t);
}
}
cout<<(res==1e9? -1: res)<<endl;
return 0;
}
D
注意到商品的种类数并不多,我们可以从此入手。
考虑每种商品离每个点 的最短路。
这就是一个多源 bfs 问题。
考虑对于每种商品 ,将 所在的所有点作为源点求一次 bfs 即可。
const int N=1e5+5, M=N<<1;
int n, m, k, s;
struct Edge{
int to, next;
}e[M];
int h[N], tot;
void add(int u, int v){
e[tot].to=v, e[tot].next=h[u], h[u]=tot++;
}
vector<int> node[N];
int d[N][110];
bool vis[N];
void build(vector<int> &P, int ty){
queue<int> q;
rep(i,1,n) vis[i]=false;
for(auto i: P) q.push(i), vis[i]=true;
vector<int> dis(n+1);
while(q.size()){
int u=q.front(); q.pop();
for(int i=h[u]; ~i; i=e[i].next){
int go=e[i].to;
if(!vis[go]){
vis[go]=true;
dis[go]=dis[u]+1;
q.push(go);
}
}
}
rep(i,1,n) d[i][ty]=dis[i];
}
int main(){
memset(h, -1, sizeof h);
cin>>n>>m>>k>>s;
rep(i,1,n){
int x; read(x);
node[x].pb(i);
}
rep(i,1,m){
int u, v; read(u), read(v);
add(u, v), add(v, u);
}
rep(i,1,k) build(node[i], i);
rep(i,1,n){
sort(d[i]+1, d[i]+1+k);
int res=0;
rep(j,1,s) res+=d[i][j];
cout<<res<<' ';
}
cout<<endl;
return 0;
}
E
注意到每一次交换,逆序对的奇偶性都会发生变化,而且,注意到 一定为奇数,也就是二人的所得到的排列逆序对数一定不同,所以通过此来判断即可。
#define int long long
const int N=1e6+50;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
int res, n, w[N], tmp[N];
void cdq(int l, int r){
if(l>=r) return;
int mid=l+r>>1;
cdq(l, mid), cdq(mid+1, r);
int sum=0;
for(int k=l, i=l, j=mid+1; k<=r; k++)
if(j>r || i<=mid && w[i]>w[j]) sum++, tmp[k]=w[i++];
else tmp[k]=w[j++], res+=sum;
for(int k=l; k<=r; k++) w[k]=tmp[k];
}
signed main(){
n=read();
for(int i=1; i<=n; i++) w[i]=read();
cdq(1, n);
cout<<((res-3*n)&1? "Um_nik": "Petr")<<endl;
return 0;
}
F
分析
思想比较有意思的图论题。
为了符合习惯,这里约定 代表题目所给的点的编号, 是值域(同时也代表全集)。
考虑建图。
首先对图进行加点,将点数补至 。
记一个点的编号为 ,那么它能够到达的极大的点编号为 ,并且 能够到达的所有点编号一定是 的子集,考虑将 向 连边。
因此对于题目所给的每个点 ,我们需要设计一个算法,将它能够到达的所有点进行标记(访问),并相应地更新答案。
具体地,可以从 出发做一遍 dfs:沿着 能到达的点继续搜。但同时, 的子集也需要标记,直接枚举是 肯定行不通,故考虑对 对应的二进制数位进行枚举,这样就能将枚举的复杂度控制在 。
// Problem: F. AND Graph
// Contest: Codeforces - Codeforces Round #485 (Div. 2)
// URL: https://codeforces.com/contest/987/problem/F
// Memory Limit: 256 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define x first
#define y second
using pii = pair<int, int>;
using ll = long long;
inline void read(int &x){
int s=0; x=1;
char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=1<<22|1, M=N;
int id[N];
int n, m;
struct Edge{
int to, next;
}e[M];
int h[N], tot;
void add(int u, int v){
e[tot].to=v, e[tot].next=h[u], h[u]=tot++;
}
bool vis[N];
void dfs(int u){
vis[u]=true;
rep(i,0,m-1) if(u>>i&1){
int go=u^(1<<i);
if(!vis[go]) dfs(go);
}
for(int i=h[u]; ~i; i=e[i].next){
int go=e[i].to;
if(!vis[go]) dfs(go);
}
}
int main(){
memset(h, -1, sizeof h);
cin>>m>>n;
int U=(1<<m)-1;
rep(i,1,n) read(id[i]);
rep(i,1,n) add(id[i], id[i]^U);
int res=0;
rep(i,1,n) if(!vis[id[i]]){
res++;
vis[id[i]]=true;
dfs(id[i]^U);
}
cout<<res<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2021-03-11 【DP】解析 SOSdp(子集和 dp)