Educational Codeforces Round 86 (Rated for Div. 2)

A. Road To Zero

题意

两个操作:操作1:花费a元使某个数加1或减1
操作2:花费b元使两个数都加1或减1
问使两个数都变为0的最小花费

思路

因为不知道a,b的大小,需要考虑所有情况,比较得出最小值

Code:

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 3e5+5;
ll t,x,y,a,b;

int main(){
	cin>>t;
	while(t--){
		cin>>x>>y>>a>>b;
		if(x>y) swap(x,y);
		ll ans=0,ans1=0;
		ans1=(abs(x)+abs(y))*a;
		ll x1=min(abs(x),abs(y));//考虑了x,y小于0的情况,此题可以不用绝对值
		ll y1=max(abs(x),abs(y));
		if(x*y>0){
			ans=x1*b+(y1-x1)*a;
		}
		else {
			ans=x1*b+(x1+y1)*a;
		}
		cout<<min(ans,ans1)<<"
";
	}

	return 0;
}

B. Binary Period

题意

给出t字符串,找出s字符串,t是s的子序列,并且s的周期最小

思路

由于s由'0','1'组成,所以s周期最多为2

code:

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 3e5+5;
int n;
string t;

int main(){
	cin>>n;
	while(n--){
		cin>>t;
		string s="";
		int flag1=0,flag2=0,flag=0;
		for(int i=0;i<t.length();i++){
			if(t[i]=='0') flag++,flag1++;
			else if(t[i]=='1') flag++,flag2++;
		}
		if(flag1>0&&flag2>0){
			if(t[0]=='0'){
				for(int i=0;i<flag1+flag2;i++){
					s+="01";
				}

			}
			else {
				for(int i=0;i<flag1+flag2;i++){
					s+="10";
				}
			}
		}
		else s=t;
		cout<<s<<'
';
	}

	return 0;
}

C. Yet Another Counting Problem

题意

在[l,r]中找到x%a%b!=x%b%a的个数

思路

打表可以发现以lcm(a,b)为周期,使x%a%b= =x%b%a的数是lcm(a,b)~lcm(a,b)+max(a,b)-1,然后在每个周期将这些数减掉即可

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
ll t,n,m,a,b,q,l,r;

ll solve(ll x,ll mx,ll lcm)
{
	if(x%lcm>=mx) return x/lcm*(lcm-mx)+(x%lcm)-mx+1;
	else
	{
		return x/lcm*(lcm-mx);
	}
}
int main(){
	cin>>t;
	while(t--){
		cin>>a>>b>>q;
		ll mx=max(a,b),lcm=a*b/__gcd(a,b);
		while(q--)
		{
			cin>>l>>r;
			cout<<solve(r,mx,lcm)-solve(l-1,mx,lcm)<<'
';
		}
	}

	return 0;
}

D. Multiple Testcases

题意

将一些测试的数组重新分配在一些测试样例中,每个新的测试样例中大于等于i的数组数目必须小于等于c[i]

解题思路

方法1:先将m数组排序,res数组统计每个样例中放入数组的数目,将m数组中的元素从大到小放入vector,x表示第一个小于c[m[i]]的数,
方法2:另一种方法,找到最大分组数,然后将数组分别加入最大分组数即可(来自https://www.cnblogs.com/stelayuri/p/12785409.html)

Code:

//方法1代码:
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 2e5+5;
ll m[N],c[N],res[N],n,k;
vector<ll>ve[N];

int main(){
	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+n+1);
	ll ans=1;
	for(int i=n;i;i--){//res表示重新分配的样例中数组数量的负值
		int x=upper_bound(res+1,res+ans+1,-c[m[i]])-res;
		if(x<=ans){
			ve[x].push_back(m[i]);
			res[x]--;
		}
		else ve[++ans].push_back(m[i]),res[x]--;
	}
	cout<<ans<<'
';
	for(int i=1;i<=ans;i++){
		cout<<ve[i].size();
		for(int j=0;j<ve[i].size();j++){
			cout<<' '<<ve[i][j];
		}
		cout<<'
';
	}


	return 0;
}

//方法2代码

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 2e5+5;
ll m[N],c[N],res[N],n,k;
vector<ll>ve[N];

int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>m[i];
		res[m[i]]++;
	}
	for(int i=1;i<=k;i++) cin>>c[i];
	sort(m+1,m+n+1);
	ll q=1;
	for(int i=k;i;i--){
		res[i]+=res[i+1];//表示大于等于i的数字数量
		ll tmp=ceil(1.0*res[i]/c[i]);
		q=max(q,tmp);//最大分组数
	}
	for(int i=1;i<=n;i++){
		ve[i%q].push_back(m[i]);
	}
	cout<<q<<'
';
    for(int i=0;i<q;i++)
    {
        cout<<ve[i].size();
        for(auto it:ve[i])
            cout<<' '<<it;
        cout<<'
';
    }

	return 0;
}
七月在野,八月在宇,九月在户,十月蟋蟀入我床下
原文地址:https://www.cnblogs.com/voids5/p/12788741.html