Codeforces Round #655 (Div. 2) 題解 (ABCD)


又一次測評姬事故現場

A. Omkar and Completion

就。。全1挺好的

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
#define endl "\n"
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int N=61; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<int,int> pii;
const int mod=(999983); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
#define int ll
void Solve(){
	int n=read();
	repeat(i,0,n)cout<<"1 ";
	cout<<endl; 
}
signed main(){
	int T=1; T=read();
	while(T--)Solve();
	return 0;
}

B. Omkar and Last Class of Math

HOW TO 快速切題?那就寫幾個例子找規律然后就秒切了

結論是 \(a=n\) 的最大的不等於 \(n\) 的約數,以下是證明:

假設 \(a\le b\),那么顯然 \(lcm\) 一定 \(\ge b\)。這里我們一定要構造 \(lcm=b\) 的解,因為 \(b\) 一定 \(<n\),而 \(lcm\)\(b\) 的倍數,就算 \(lcm=2b\) 也一定 \(\ge n\),舍

我們證明了 \(lcm=b\) 也就是說,\(a\) 可以整除 \(b\),這又等價於 \(a\) 整除 \(n\)。我們又要讓 \(lcm\) 盡可能小,相當於讓 \(b\) 盡可能小也就是 \(a\) 盡可能大。所以總結一下,要讓 \(a\) 整除 \(n\) 並且 \(a\) 盡可能大,那就找 \(n\) 的最大的不等於 \(n\) 的約數就好了(語無倫次

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
#define endl "\n"
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int N=61; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<int,int> pii;
const int mod=(999983); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
#define int ll
void Solve(){
	int n=read();
	repeat(i,2,sqrt(n)+2){
		if(n%i==0){
			cout<<n/i<<' '<<n-n/i<<endl;
			return;
		}
	}
	cout<<1<<' '<<n-1<<endl;
}
signed main(){
	int T=1; T=read();
	while(T--)Solve();
	return 0;
}

C. Omkar and Baseball

大意:問最少要多少次操作讓一個排列變成 \([1,2,..,n]\)。操作是,選擇一個區間,重新排列使得所有區間內的數都不在原來位置上

分三種情況討論:原序列已經是 \([1,2,..,n]\);原序列中,有一段區間中所有元素都錯位;其他情況

這三種情況分別輸出0,1,2。為什么最多2次操作就行了呢?因為。。沒想法

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
#define endl "\n"
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<int,int> pii;
const int mod=(999983); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
#define int ll
int a[N];
void Solve(){
	int n=read();
	repeat(i,0,n){
		a[i]=read()==i+1;
	}
	a[n]=1; int cnt=0;
	repeat(i,0,n)
	if(!a[i] && a[i+1])
		cnt++;
	if(*min_element(a,a+n)==1)cout<<0<<endl;
	else if(cnt==1)cout<<1<<endl;
	else cout<<2<<endl;
}
signed main(){
	int T=1; T=read();
	while(T--)Solve();
	return 0;
}

D. Omkar and Circle

大意:環上n個非負數,n是奇數,每次操作選擇一個數,把這個數變成相鄰兩個數之和,並刪除相鄰兩個數。求若干操作后環上的最后一個數的最大值

首先把環斷開,分析一波,發現最優情況只可能是把所有奇數位置上的數加起來。因為偶數位置的數根本不可能留到最后。那么這個結論應用到環上就是,很多“偶數”位置其實都會被拋棄,最后的答案一定是,選取恰當的位置把環斷開后的奇數位置之和。(感覺是這樣的)所以實現的時候只要記錄奇偶位置的前綴和,然后for一遍即可

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
#define endl "\n"
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
//mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<int,int> pii;
const int mod=(999983); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
#define int ll
int a[N],s[2][N];
void Solve(){
	int n=read();
	repeat(i,1,n+1){
		a[i]=read();
		s[0][i]=s[0][i-1]+(i%2==0?a[i]:0);
		s[1][i]=s[1][i-1]+(i%2==1?a[i]:0);
	}
	int ans=0;
	repeat(i,1,n+1){
		ans=max(ans,s[i%2][i]+s[i%2^1][n]-s[i%2^1][i]);
	}
	cout<<ans<<endl;
}
signed main(){
	int T=1; //T=read();
	while(T--)Solve();
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM