Educational Codeforces Round 86 (Rated for Div. 2)(A,B,C,D題解)

遲到的補題。。。。
在這裏插入圖片描述
在這裏插入圖片描述

題意:
你可以用花費aa元,使得xx或者yy不同時加11或者減11,你也可以花費bb元使得x,yx,y同時加11或者減11,問你最少花費多少錢使得x=y=0x=y=0
思路:
無論你是同時還是單一操作,你都要先使得x=yx=y,然後再考慮使用同時加減還是單一加減更優。
代碼:

#include<bits/stdc++.h>
using namespace std;
 
const int maxn = 2e5 + 10;
typedef long long int ll;
void solved(){
	int t;cin>>t;
	while(t--){
		ll x,y,a,b;cin>>x>>y>>a>>b;
		cout<<(max(x,y)-min(x,y)) * a + min(min(x,y) * b,min(x,y) * 2 * a)<<endl;
	}	
}
int main(){
	solved();
	return 0;
} 

在這裏插入圖片描述
在這裏插入圖片描述
題目大意:
給你一個0101字符串tt,要你生產一個字符串ss,使得ttss的子串,並且ss的循環週期最短並且ss的長度<=2t<=2t
思路:
容易發現如果tt本身只包含010或者1字符串的時候,循環週期爲11且最短,這個時候直接輸出即可。當tt包含0101字符串的時候我們不可能生產出比周期11更短的字符串,但是週期22確實可以生產的,只需要保證ss的長度是tt的兩倍,那麼tt一定是ss的字串,並且把ss生成01010101...0101010101...01這樣的字符串即可,因爲週期爲22最短。
代碼:

#include<bits/stdc++.h>
using namespace std;
 
const int maxn = 2e5 + 10;
typedef long long int ll;
void solved(){
	int t;cin>>t;
	while(t--){
		string s;cin>>s;
		int f1 = 0,f0 = 0;
		for(int i = 0; i < s.size(); i++){
			if(s[i] == '1')f1 = 1;
			if(s[i] == '0')f0 = 1;
		}
		if(f1 && f0){
			for(int i = 0; i < s.size(); i++){
				cout<<"01";
			}
			cout<<endl;
		}else{
			cout<<s<<endl;
		}
	}
}
int main(){
	solved();
	return 0;
} 

在這裏插入圖片描述
題目大意:
給你兩個十進制數字a,ba,b,和qq個詢問,每個詢問包含一個區間L,RL,R,問你這個區間滿足 xx%aa%b !=!=xx%bb%aa的數有多少個。
思路:
x<max(a,b)x<max(a,b)的時候一定不滿足。
我們可以發現當x=lcm(a,b)x=lcm(a,b)的時候xx%aa%b ==xx%bb%aa,並且lcm+max(a,b)lcm+max(a,b)這一段都不滿足,進而可以推廣klcm+max(a,b)klcm+max(a,b)這些段不滿足,換言之,lcmmax(a,b)lcm - max(a,b)是滿足條件的。所以我們需要在L,RL,R找有多少個lcmlcm,可以R/lcmL/lcmR/lcm - L /lcm找出lcmlcm個數,當然還要考慮邊界情況,把R可以少加的Rmax(a,b)+1R- max(a,b) + 1加上,把L可能少減的Lmax(a,b)L - max(a,b)減掉就行了。
代碼:

#include<bits/stdc++.h>
using namespace std;
 
typedef long long int ll;
void solved(){
	int t;cin>>t;
	while(t--){
		ll a,b,q;cin>>a>>b>>q;
		ll lcm = a / __gcd(a,b) * b;
		while(q--){
			ll l,r;cin>>l>>r;
			if(r < max(a,b)){
				cout<<"0"<<endl;
			}else{
				ll n = r / lcm - l / lcm;
				ll ans = n * (lcm - max(a,b));
				r %= lcm;
				if(r >= max(a,b))ans += r - max(a,b) + 1;
				l %= lcm;	
				if(l > max(a,b))ans -= l - max(a,b);
				cout<<ans<<" ";
			}
		}
		cout<<endl;
	}
}
int main(){
	solved();
	return 0;
} 

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
題目大意:
給你nn個數,要你分組,每組需要滿足>=1>=1的個數不超過CiCi,。。。>=k>=k的個數不超過CkCk。要你使得分組數最少,並且輸出分組方案。
思路:
爲了方便處理先把所有數升序,然後找滿足大於等於aiai的數有多少個//cici,向上取整然後去最大值,就是最小方案數了。你可以這樣理解,最大值並且大於其他所有數,其他所有分組數都滿足了,這個時候只需要滿足最大的這個數了,就會滿足所有情況。然後把每個數依次分組填入即可(即將最大峯值縮小)。
核心:max(si/ci)max(si/ci)向上取整
代碼:

#include<bits/stdc++.h>
using namespace std;
 
typedef long long int ll;
const int maxn = 2e5 + 10;
int m[maxn],c[maxn];
vector<int>ve[maxn];
void solved(){
	int n,k;cin>>n>>k;
	for(int i = 1; i <= n; i++)cin>>m[i];
	for(int i = 1; i <= k; i++)cin>>c[i];
	sort(m + 1, m + 1 + n);
	int ans = 0;
	for(int i = 1; i <= n; i++){
		ans = max(ans,((n - i + 1) - 1) / c[m[i]] + 1);
	}
	for(int i = 1; i <= n; i++){
		ve[(i - 1) % ans].push_back(m[i]);
	}
	cout<<ans<<endl;
	for(int i = 0; i < ans; i++){
		cout<<ve[i].size()<<" ";
		for(int j = 0; j < ve[i].size(); j++){
			cout<<ve[i][j]<<" ";
		}
		cout<<endl;
	}
}
int main(){
	solved();
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章