C/C++教程

Codeforces Round #775 (Div. 2)补题记录 A-D

本文主要是介绍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练习!!一定要留下来啊!!!

这篇关于Codeforces Round #775 (Div. 2)补题记录 A-D的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!