CF339 题解
CF339 题解
这套题虽然是div2,但是具有一定的价值,这套题作为典型的div2题目,全套5道题都几乎用暴力方法解决,但是为什么这样是对的?令人深思。
A
红题,把个位数提出来再排序就好了。
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
char s[N];
int n,num[N],tot = 0;
int main()
{
scanf("%s",s + 1);
n = strlen(s + 1);
for(int i = 1;i <= n;i++)
{
if(s[i] == '+') continue;
num[++tot] = s[i] - '0';
}
sort(num + 1,num + tot + 1);
for(int i = 1;i <= tot - 1;i++) cout<<num[i]<<"+";
cout<<num[tot];
return 0;
}
B
路径只有一种,记录当前位置,下一个目标如果大于当前位置,就走小半圈,如果小于当前位置,就绕过1号节点一次,把距离加起来就好了。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
long long tp = 0;
int a[N],n,m;
int main()
{
cin>>n>>m;
for(int i = 1;i <= m;i++) cin>>a[i];
int np = 1;
for(int i = 1;i <= m;i++) tp += (np <= a[i] ? a[i] - np : a[i] + n - np),np = a[i];
cout<<tp;
return 0;
}
C
比赛才刚刚开始!
这道题其实可以导出一个但是我写挂了。
正解还是很逆天,首先提取出哪些砝码可以用,然后暴力从第一个开始
看上去是一个
#include<bits/stdc++.h>
using namespace std;
int a[11],tot = 0,m,q[1005];
inline void dfs(int x,int ls,int rs,int last)
{
if(x == m + 1)
{
puts("YES");
for(int i = 1;i <= m;i++) cout<<q[i]<<" ";
exit(0);
}
for(int i = 1;i <= tot;i++)
{
if(a[i] == last) continue;
if(x & 1)
{
if(ls + a[i] > rs) q[x] = a[i],dfs(x + 1,ls + a[i],rs,a[i]);
}
else
if(rs + a[i] > ls) q[x] = a[i],dfs(x + 1,ls,rs + a[i],a[i]);
}
}
int main()
{
char s[11];
scanf("%s",s + 1);
for(int i = 1;i <= 10;i++) if(s[i] == '1') a[++tot] = i;
scanf("%d",&m);
dfs(1,0,0,0);
puts("NO");
return 0;
}
D
感觉比较奇葩...
这个题我们发现它是
分层...合并...
线段树!
所以从底层开始记录线段树高度,直接单点修改维护即可。板子题,CF特有的CD题难度逆序对。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int t[N * 4],dep[N * 4],n,m;
inline void pushup(int pos)
{
if(dep[pos] & 1) t[pos] = t[pos << 1] | t[pos << 1 | 1];
else t[pos] = t[pos << 1] ^ t[pos << 1 | 1];
}
inline void build(int l,int r,int pos)
{
if(l == r)
{
cin>>t[pos];
dep[pos] = 0;
return;
}
int mid = (l + r) >> 1;
build(l,mid,pos << 1);
build(mid + 1,r,pos << 1 | 1);
dep[pos] = dep[pos << 1] + 1;
pushup(pos);
}
inline void modify(int l,int r,int x,int k,int pos)
{
if(l == r)
{
t[pos] = k;
return;
}
int mid = (l + r) >> 1;
if(x <= mid) modify(l,mid,x,k,pos << 1);
else modify(mid + 1,r,x,k,pos << 1 | 1);
pushup(pos);
}
int main()
{
cin>>n>>m;
n = 1 << n;
dep[1] = 0;
build(1,n,1);
int x,y;
for(int i = 1;i <= m;i++)
{
cin>>x>>y;
modify(1,n,x,y,1);
cout<<t[1]<<endl;
}
return 0;
}
E
三步指的是题目保证三步有解(谴责翻译)。
考虑将这个变成一个逆序过程,即将原排列翻成
#include<bits/stdc++.h>
using namespace std;
const int N = 1005;
pair<int,int> q[4];
int a[N],n;
inline bool sorted()
{
for(int i = 1;i <= n;i++) if(a[i] != i) return 0;
return 1;
}
inline void solve(int x)
{
if(sorted())
{
cout<<x - 1<<endl;
for(int i = x - 1;i >= 1;i--)
cout<<q[i].first<<" "<<q[i].second<<endl;
exit(0);
}
if(x >= 4) return;
int now[15],top = 0;
now[++top] = 1;
now[++top] = n;
for(int i = 2;i <= n;i++)
if(abs(a[i] - a[i - 1]) > 1)
now[++top] = i - 1,now[++top] = i;
sort(now + 1,now + top + 1);
top = unique(now + 1,now + top + 1) - (now + 1);
for(int i = 1;i <= top;i++)
for(int j = i + 1;j <= top;j++)
{
q[x] = make_pair(now[i],now[j]);
reverse(a + now[i],a + now[j] + 1);
solve(x + 1);
reverse(a + now[i],a + now[j] + 1);
}
}
int main()
{
cin>>n;
for(int i = 1;i <= n;i++)
cin>>a[i];
solve(1);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话