Educational Codeforces Round 86 (Rated for Div. 2) AtoD

[链接](https://codeforces.com/contest/1342)

A

简单签到题,直接判断一次去掉两个的花费是不是比一个一次去更贵就可以


菜鸡代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<int,int>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof j)
#define rrep(i,j,k) for(int i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define end end()
#define all(x) x.begin(),x.end()
const int N=2e5+10;
int main(int argc, char const *argv[])
{
	// #define DEBUG
	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	int _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	while(_--){
			LL a,b,c,d;
			cin>>a>>b>>c>>d;
			LL cost = 0;
			LL mi = min(a,b);
			LL gap = abs(a-b);
			if(d>2*c) 
				cost = (a+b)*c; 
			else
				cost = mi*d+gap*c;
			cout<<cost<<endl;
	}
	return 0;
}

B

思路

简单构造,因为s的长度可以是t的两倍,那么t必然是可以由s得到
注意到这样一个情况,当t既含有0又有1的话,要使得s的循环节最小
那么s只能是01重复循环,如果t只含有0或者1,那么s直接取t就可以


弱鸡代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<int,int>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof j)
#define rrep(i,j,k) for(int i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define end end()
#define all(x) x.begin(),x.end()
const int N=505;
int main(int argc, char const *argv[])
{
	// #define DEBUG
	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	int _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	while(_--){
			string t;
			cin>>t;
			string ans = "";
			int a=0;
			int b=0;
			rep(i,0,t.length())
				if(t[i]=='0')
					a++;
				else
					b++;
			if(a==t.length()||b==t.length())
				ans = t;
			else{
				rep(i,0,t.length())
					ans+="10";
			}
			cout<<ans<<endl;
	}
	return 0;
}

C


思路

注意到这样一个事实,设lcm是a,b的最小公倍数,那么m=lcm*k+i%a%b=i%a%b for all i in[1,lcm],
原因是前一部分直接第一次取模就去掉了,所以可以预处理1到lcm有多少个数,求一遍前缀和就可以了。


代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<int,int>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof j)
#define rrep(i,j,k) for(int i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define end end()
#define all(x) x.begin(),x.end()
const int N=40010;
bool is[N];
long long cnt[N];
vector<LL> ans;
inline long long cal(LL a,LL lc){
	LL temp = a/lc;
	LL gg = a%lc;
	LL res =  cnt[lc]*temp+cnt[gg];
	return res;
}
int main(int argc, char const *argv[])
{
	// #define DEBUG
	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	int _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	while(_--){
		LL a,b,q;
		cin>>a>>b>>q;
		LL gc = __gcd(a,b);
		LL lc = a*b/gc;
		LL c = 0;
		// LL ans=0;
		rep(i,1,lc+10){
			if((i%a)%b!=(i%b)%a){
				is[i]=true;
				++c;
			}
			cnt[i]=c;
		}
		ans.clear();
		rep(i,0,q){
			cin>>a>>b;
			ans.pb(cal(b,lc)-cal(a-1,lc));

		}
		rep(i,0,ans.size())
			cout<<ans[i]<<" ";
		cout<<endl;

	}
	return 0;
}

D

思路

直接转化,贪心的从后往前做,需要注意的是,如果b[i]>b[i+1]那么最优的做法是从第一个结果子集
再开始放这样维护了每个子集已用的个数是非增,同时如果b[i]=b[i+1]那么,就要从当前放到的子集的下一个开始放,
因为递推的过程中是每一个b[i]都贪心的用完的。 弱鸡在这里T成了🐕




代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<int,int>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof j)
#define rrep(i,j,k) for(int i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define end end()
#define all(x) x.begin(),x.end()
const int N=2e5+10;
int a[N];
int b[N];
int cnt[N];
vector<int> ans[N];
int main(int argc, char const *argv[])
{
	int m,k;
	int t;
	cin>>m>>k;
	rep(i,0,m){
		cin>>t;
		a[t]++;
	}
	rep(i,0,k){
		cin>>b[i];
	}
	int cur=0;
	rrep(i,k,0){
		if(b[i-1]!=b[i])
			cur=0;
		t=a[i];
		while(t>0)
		{
			while(cnt[cur]==b[i-1])cur++;
			ans[cur].pb(i);
			cnt[cur]++;
			t--;
		}
	}
	int res=0;
	while(ans[res].size()) res++;
	cout<<res<<endl;
	rep(i,0,res){
		cout<<ans[i].size()<<" ";
		rep(j,0,ans[i].size())
			cout<<ans[i][j]<<" ";
		cout<<endl;
	}
	return 0;
}
posted @ 2020-04-27 11:16  CrosseaLL  阅读(145)  评论(0编辑  收藏  举报