Codeforces Round #775 (Div. 2)补题记录 A-D
A
https://codeforces.com/contest/1649/problem/A
最多只能跳一次,从第一个0的前一个位置跳到最后一个0的下一个位置,循环找出位置后处理即可
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N =100005;
int n,t;
int a[105];
string s;
int main(){
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int ans=0;
int l=0,r=0; ///1
for(int i=1;i<=n;i++){
if(a[i]==0){
l=i-1;
break;
}
}
for(int i=n;i>=1;i--){
if(a[i]==0){
r=i+1;
break;
}
}
if(l>=r) ans=0;
else ans=r-l;
cout<<ans<<endl;
}
return 0;
}
B
https://codeforces.com/contest/1649/problem/B
样例要稍微认真看看,思路为贪心。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N =100005;
int n,t;
int a[N];
string s;
int main(){
cin>>t;
while(t--){
cin>>n;
ll s=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
s+=a[i];
}
if(s==0){
puts("0");
continue;
}
sort(a+1,a+n+1);
if(a[n]>s-a[n]+1){
cout<<a[n]-(s-a[n])<<endl;
}
else puts("1");
}
return 0;
}
C
https://codeforces.com/contest/1649/problem/C
思路很好想:由曼哈顿距离的定义,我们可以分开考虑相同颜色的点的横纵坐标,先用一个数据结构存一下每个点的颜色、横纵坐标,然后把点对间的贡献算进答案。
那么要怎么算呢?
我首先没有分析时间复杂度,写了一个O(color.size()*cord.size()^2)的做法,就是统计每种颜色下每个位置的点的个数,结果超时了
倒是想复杂了,可以O(cord.size())求出不同颜色的点的横(纵)坐标,排序后,利用类似前缀和的思想跑一趟循环,即可求出答案
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N =100005;
int n,t,x,m;
set<int>color;
vector<int>row[N],col[N]; ///col/row[color]={pos,cnt}
vector<pair<int,int>>r;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&x);
if(color.count(x)==0) color.insert(x);
row[x].push_back(i);
col[x].push_back(j);
}
}
ll ans=0;
for(auto i=color.begin();i!=color.end();i++){
sort(row[*i].begin(),row[*i].end());//
for(int j=0;j<row[*i].size();j++){
ans+=1ll*row[*i][j]*j-row[*i][j]*(row[*i].size()-j-1);
}
sort(col[*i].begin(),col[*i].end());
for(int j=0;j<col[*i].size();j++){
ans+=1ll*col[*i][j]*j-col[*i][j]*(col[*i].size()-j-1);
}
}
printf("%lld\n",ans);
return 0;
}
D
https://codeforces.com/contest/1649/problem/D
可以O(clogc)求解。
先给数组排序,对于每一个位于[1,c]区间的数i,枚举它的倍数j,先在数组中找有没有位于[i,i+j)范围内的数,如果有,那么j/i也必须存在,否则不满足条件 这样判断
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N =1000005;
int n,t,c;
int a[N];
//map<int,int>vis;
bool vis[N];
bool check(){
if(vis[1]==0){
return 0;
}
for(int i=1;i<=c;i++){
if(vis[i]==0) continue;
for(int j=2*i;j<=c;j+=i){
int ind=lower_bound(a+1,a+n+1,j)-a;
if(ind<=n&&a[ind]<j+i){
if(!vis[j/i]){
return 0;
}
}
}
}
return 1;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&c);
for(int i=1;i<=c;i++) vis[i]=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
vis[a[i]]=1;
}
sort(a+1,a+n+1);
if(check()==1) puts("Yes");
else puts("No");
}
return 0;
}
注意一下能用数组就不要用map存!!本题就会超时的
总结
又好久没打cf,A题一上来wa了一发,罚时++;B题竟然因为数组范围写错fst了。。。C题这样的题见少了,类似前缀和思想,tle了;D有思路做不对,emmm还是题目写少了吧,细节注意的不够
cf平时还是要多打打,可以练习思维,也提高了debug能力。
目标:每天一套div2练习!!一定要留下来啊!!!
分类:
cf
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧