Codeforces Round #481 (Div. 3)(A-G)題解
A. Remove Duplicates
思路:先用一個記錄那些數出現過,儲存他們最後一次出現位置,然後排個序輸出即可。
時間複雜度:
實際上不用排序,直接順序遍歷對應匹配輸出即可。
#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
思路:貪心。顯然還有三個及以上的子串必須刪掉,所以我們可以順序遍歷,如果當前有這樣的串,以非結束,我們就計算貢獻,這樣的串的貢獻是:。
注意最後循環外還需要判一次,因爲可能全部是串。
時間複雜度:
#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
思路:模擬水題,直接記錄前綴和,然後每次二分查找到小於的最大前綴和對應的下標,即是宿舍編號,然後房間號是
時間複雜度:
#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
思路:暴力。這題有點意思,要求我們構造一個等差序列。要求每個數不能操作超過一次。顯然如果顯然直接輸出0.
否則我們可以枚舉第一項,第二項,來確定首項和公差,從而確定整個數組。
接下看每種情況是否滿足即可,取最小操作數。
時間複雜度: ,因爲第一項和第二項分別最多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
思路:模擬水題,初始化,然後每次更新區間。
.
一邊遍歷一邊更新答案即可。
時間複雜度:
#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
思路:這題挺好的,反向考慮,首先我們確定每個人比他技能值小的人數有多少個。
然後在遍歷每個關係時,如果,說明將他們減去,這樣剩下的就是答案了。
時間複雜度:
#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
思路:類似活動安排的貪心思路,我們只需要將區間安排變成,一天一天地安排。
按照結束時間最早的最先安排,這樣爲後面的考試有更多安排的空間。
時間複雜度:
#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;
}