Codeforces Round #481 (Div. 3)(A-G)題解

Codeforces Round #481 (Div. 3)(A-G)題解

傳送門

A. Remove Duplicates

思路:先用一個vis[]vis[]記錄那些數出現過,儲存他們最後一次出現位置,然後排個序輸出即可。

時間複雜度:O(n)O(n)

實際上不用排序,直接順序遍歷對應匹配輸出即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=50+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
int a[N],vis[1005];
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int cnt=0;
	for(int i=n;i>=1;i--){
		if(vis[a[i]]) continue;
		vis[a[i]]=i;
		cnt++;
	}
	sort(vis+1,vis+1001);
	cout<<cnt<<endl;
	for(int i=1;i<=1000;i++){
		if(vis[i]) printf("%d ",a[vis[i]]);
	}
	return 0;
}

B. File Name

思路:貪心。顯然還有三個xx及以上的子串必須刪掉xx,所以我們可以順序遍歷,如果當前有這樣的串,以非xx結束,我們就計算貢獻,這樣的串的貢獻是:len(str)2len(str)-2

注意最後循環外還需要判一次,因爲可能全部是xx串。

時間複雜度:O(n)O(n)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=50+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
int a[N];
int main(){
	int n;
	cin>>n;
	string s;
	cin>>s;
	int ans=0,cnt=0;
	for(int i=0;i<n;i++){
		if(s[i]!='x'){
			if(cnt>=3) ans+=cnt-2;
			cnt=0;
		}
		else cnt++;
	}
	if(cnt>=3) ans+=cnt-2;
	cout<<ans<<endl;
	return 0;
}

C. Letters

思路:模擬水題,直接記錄前綴和,然後每次二分查找到小於xx的最大前綴和對應的下標ppp+1p+1即是宿舍編號,然後房間號是xpre[p]x-pre[p]

時間複雜度:O(nlogn)O(nlogn)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
ll a[N],pre[N];
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		pre[i]=pre[i-1]+a[i];
	}
	for(int i=1;i<=m;i++){
		ll x;
		scanf("%lld",&x);
		int p=lower_bound(pre+1,pre+n+1,x)-pre;
		p--;
		x-=pre[p];
		printf("%d %lld\n",p+1,x);
	}
	return 0;
}

D. Almost Arithmetic Progression

思路:暴力。這題有點意思,要求我們構造一個等差序列。要求每個數不能操作超過一次。顯然如果n2n\leq2顯然直接輸出0.

否則我們可以枚舉第一項,第二項,來確定首項和公差,從而確定整個數組。

接下看每種情況是否滿足即可,取最小操作數。

時間複雜度:O(25n)O(25n) ,因爲第一項和第二項分別最多5種情況。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
ll a[N];
int n;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	if(n<=2) return puts("0"),0;
	int ans=1e9,cnt=0;
	for(int x=a[1]-1;x<=a[1]+1;x++){
		for(int y=a[2]-1;y<=a[2]+1;y++){
			cnt=abs(x-a[1])+abs(y-a[2]);
			int f=0;
			ll d=y-x;
			for(int i=3;i<=n;i++){
				ll tmp=x+d*(i-1);
				//printf("%d, tmp=%d\n",i,tmp);
				if(abs(tmp-a[i])>1){
					f=1;
					break;
				}
				else cnt+=abs(tmp-a[i]);
			}
			if(!f) ans=min(ans,cnt);
		}
	}
	printf(ans==1e9?"-1":"%d\n",ans);
	return 0;
}

E. Bus Video System

思路:模擬水題,初始化l=0,r=wl=0,r=w,然後每次更新區間。

x+ai[0,w]x[sum,wsum]x+\sum a_i\in[0,w]\rightarrow x\in[-sum,w-sum].

一邊遍歷一邊更新答案即可。

時間複雜度:O(n)O(n)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
int a[N];
int main(){
	int n,w; 	
	scanf("%d%d",&n,&w);
	int sum=0,l=0,r=w;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		sum+=a[i];
		l=max(l,-sum),r=min(w-sum,r);
	}
	if(l>r||l<0||r>w) puts("0");
	else printf("%d\n",r-l+1); 
	return 0;
}

F. Mentors

思路:這題挺好的,反向考慮,首先我們確定每個人比他技能值小的人數有多少個。

然後在遍歷每個關係時,如果a[x]<a[y]a[y]>a[x]a[x]<a[y]||a[y]>a[x],說明將他們減去,這樣剩下的就是答案了。

時間複雜度:O(nlogn)O(nlogn)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
int a[N],b[N],ans[N];
int main(){
	int n,k;
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]),b[i]=a[i];
	}
	sort(b+1,b+n+1);
	for(int i=1;i<=n;i++) ans[i]=lower_bound(b+1,b+n+1,a[i])-b-1;
	for(int i=1;i<=k;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		if(a[u]<a[v]) ans[v]--;
		else if(a[u]>a[v]) ans[u]--;
	}
	for(int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}

G. Petya’s Exams

思路:類似活動安排的貪心思路,我們只需要將區間安排變成,一天一天地安排。

按照結束時間最早的最先安排,這樣爲後面的考試有更多安排的空間。

時間複雜度:O(n2)O(n^2)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
int n,m;
struct p{
	int s,d,c;
}a[N];
int ans[N];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&a[i].s,&a[i].d,&a[i].c);
		ans[a[i].d]=m+1;
	}
	for(int i=1;i<=n;i++){
		if(ans[i]) continue;
		int mn=500,id;
		for(int j=1;j<=m;j++)
			if(a[j].c&&i>=a[j].s&&i<a[j].d&&a[j].d<mn) mn=a[j].d,id=j;
		if(mn!=500) ans[i]=id,a[id].c--;
	}
	for(int i=1;i<=m;i++) if(a[i].c) return puts("-1"),0;
	for(int i=1;i<=n;i++)
		printf("%d ",ans[i]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章