CF 1800~2100 思维题泛做
1648B
关键词:数学、算法优化。
给定长为 满足 的序列 。
求问是否能够保证序列 中所有满足 的两数, 也在序列中。
- 的算法
看到题目就能一眼出的算法,无非暴力枚举所有 判断。
因为有 ,可以开一个桶存一个数是否出现过,这样就能做到 判断。
时间复杂度 。
- 的算法
把直接枚举序列中的每个数,改成对于数 ,枚举 区间内的数。
时间复杂度降至 ,但还需优化。
#define L(i,j,k) for(int i=(j);i<=(k);i++)
void work(){
cin>>n>>k;L(i,1,k) t[i]=0;
L(i,1,n) cin>>a[i],t[a[i]]=1;
if(!t[1]) return cout<<"No"<<endl,void();
L(i,1,n) L(j,2,(sqrt(a[i])))
if(!(t[j]+t[a[i]/j]^1))
return cout<<"No"<<endl,void();
cout<<"Yes"<<endl;
}
- 的算法
正片开始!。
如果枚举因数不行,那就枚举倍数。
先对序列去重,特判序列中不存在 的情况直接判负。
对于 ,也就是 的情况,
如果 ,则此序列不满足条件。
可以直接在 的范围内枚举 和相应的 并判断。
上面的式子可以想到用之前处理出桶数组进行前缀和 判断。
时间复杂度 ,详见调和级数——百度百科。
提交记录
1583D
关键词:交互、拆分任务。
存在一个长度为 的排列 ,最多询问 次,求出排列 。
每次询问提交一个序列 ,会回复序列 之和所得序列中第一个出现不止一次的数的位置,没有则返回 。
。
从询问 的条件上看,可以想到将其拆成 次询问,分别实现不同的目标。
在这道题里,是从局部推至整体。
- 局部:
很明显,我们可以在 次询问内求得任意一个排列 中的数值。
除了要求的位置,序列 全赋值为 ,所求位的值从 开始递减,假设值为 时返回值不为 ,那么排列 当前位的值就是 。
根据题目中第一个出现不止一次的数的位置
的描述,先求 可以避免位置的干扰。
- 整体:
只要我们知道了 ,那就可以用 次询问求得排列 其余所有元素。
因为排列中每个数唯一,考虑将 补至 ,就能保证询问提交序列的 。
要求得数的位置必然在 之前,所以正确性也能保证。
#include <bits/stdc++.h>
using namespace std;
#define L(i,j,k) for(int i=(j);i<=(k);i++)
#define R(i,j,k) for(int i=(j);i>=(k);i--)
int a[200],ans[200],k=1,n,x;
void ask(){
cout<<"? ";L(j,1,n)
cout<<a[j]<<" \n"[j==n];
cout.flush();cin>>x;
}signed main(){
// freopen("test.in","r",stdin);
cin>>n;L(i,1,n-1) a[i]=1;
R(i,n,1){a[n]=i;ask();if(x){k=i;break;} }
ans[n]=n-k+1;a[n]=n+1-ans[n];
L(i,1,n){
L(j,1,n-1) a[j]=n+1-i;
ask();ans[x]=i;
}cout<<"! ";L(i,1,n)
cout<<ans[i]<<" \n"[i==n];
cout.flush();
}
询问次数 的做法:
设询问的数组为 ,最终答案数组 。
跟之前的做法类似,设 ,但是 从 开始枚举。
当第一次的返回为 时,就可以确定
这一过程中返回的非 信息其实也能利用。
如果当 时询问的回复是 ,那么很容易推得
这样就能在 次询问后,确定值在 范围内的数的位置。
在剩下的 次询问中,先将 设为 ,其余 中确定的值在 中对应的位置都设为 。
总共循环 次,在第 次时,将 中所有不确定的位置全设为 ,询问返回 ,则可以确定 。
这样,我们实现了在询问次数为 的情况下解决了这个问题。
提交记录
1666C
关键词:构造。
给定二维平面上 个点,用总长度最短的线段连接这 个点。求线段数和每条线段的端点。
构造题,可以想到。
将点按照 轴坐标排序,两边的点向中间连边,中间点过平行于 轴,包括三个点的线段。
如下图所示:
-----|
|
|-----
|
线段数恒为 。
#include <bits/stdc++.h>
#define F(i) a[i].first
#define S(i) a[i].second
using namespace std;
pair <int,int> a[5];
int main(){
freopen("test.in","r",stdin);
for(int i=1;i<=3;i++) cin>>F(i)>>S(i);sort(a+1,a+4);
cout<<3<<'\n'<<F(1)<<' '<<S(1)<<' '<<F(2)<<' '<<S(1)<<'\n';
cout<<F(2)<<' '<<min(S(1),min(S(2),S(3)))<<' '<<F(2)<<' '<<max(S(1),max(S(2),S(3)))<<'\n';
cout<<F(2)<<' '<<S(3)<<' '<<F(3)<<' '<<S(3);return 0;
}
1583D
关键词:交互、转化信息、读题。
因为连着读错两次题导致几乎荒废了一整个下午。
其实还是比较容易知道,只要在两次询问中排除三个人就能保证在规定次数内求解。
其实题目已经限定的很死了,整个框架已经搭好。
如果只是两个人,比一下就行。
如果是四个人,就要考虑如何两次询问排除。
比如 四人。
头脑风暴可知,先比较 ,根据结果分类讨论。
- 回复
此时 都是 场,比较 即可。
- 回复
此时 必定赢 , 必定输 ,比较 。
- 回复
和上面差不多推理,比较 。
如此实现了两次询问排除三人。
重复上述过程即可。
如果最后剩下两人就再比一次。
为什么读错题还是两次一起啊喂
int n;int ask(int x,int y){
cout<<"? "<<x<<' '<<y<<'\n';
cl;int g;cin>>g;return g;
}void out(int x){cout<<"! "<<x<<'\n';cl;}
void work(){
cin>>n;vi a(1<<n);iota(all(a),1);
while(a.size()>=4){
vi b;for(int i=0;i+3<a.size();i+=4){
int x=ask(a[i],a[i+2]);
if(!x) b.pb(ask(a[i+1],a[i+3])==1?a[i+1]:a[i+3]);
else if(x==1) b.pb(ask(a[i],a[i+3])==1?a[i]:a[i+3]);
else b.pb(ask(a[i+1],a[i+2])==1?a[i+1]:a[i+2]);
}a=b;
}out(a[0]=(a.size()==2)?a[ask(a[0],a[1])-1]:a[0]);
}
1701D
关键词:贪心,优先队列。
首先,根据题目给出的式子我们可以反向算出 的取值范围:。
现在题目转化成了,每个点对应有若干个线段。
采取贪心策略。
对于一个点,将所有以这个点为左端点的线段存入对应的数组。
之后进行贪心,对于每个点,将其对应的线段压入优先队列,每次选取右端点最小的线段。
因为选取右端点最小,使得之后的选择余地更大。
最后注意下 的情况,不能直接除,直接赋值为 即可。
#define pb push_back
#define vi vector<int>
#define pi pair<int,int>
int n;priority_queue<pi>q;
const int N=5e5+100;
int a[N],b[N];
vi p[N];pi t[N];
void work(){
cin>>n;L(i,1,n) p[i].clear();
while(!q.empty()) q.pop();
L(i,1,n) cin>>a[i];
L(i,1,n){
t[i]={i/(a[i]+1)+1,a[i]?i/a[i]:n};
p[F(t[i])].pb(i);
}L(i,1,n){
for(int x:p[i]) q.push({-S(t[x]),x});
int x=S(q.top());q.pop();a[x]=i;
}L(i,1,n) cout<<a[i]<<" \n"[i==n];
}
1485D
关键词:人类智慧
题目中有个重要信息:,限制的如此之死,绝非偶然之举。
因为 ,在题目给出的 范围内,所以可以进行构造。
进行黑白染色,区分是加上 还是不变即可。
时间复杂度:
空间复杂度:
#define L(i,k) for(int i=1;i<=(k);i++)
void work(){
int n,m,x;cin>>n>>m;L(i,n) L(j,m)
cin>>x,cout<<720720+(((i+j)&1)?0:pow(x,4))<<" \n"[j==m];
}
纯粹就是思路特阴间,代码特好写的诈骗构造题。
所以才记录这样一道 2200 的题目
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)