Codeforces Round #615(Div.3)

A - Collecting Coins

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
int main()
{
	ll q;cin>>q;
	while(q--){
		ll a,b,c,n;
		cin>>a>>b>>c>>n;
		ll zy=max(a,max(b,c));
		ll libm=zy-a+zy-b+zy-c;
		n-=libm;
		if(n<0){
			cout<<"NO"<<endl;
			continue;
		}
		if(n%3==0){
			cout<<"YES"<<endl;
		}else{
			cout<<"NO"<<endl;
		}
	}
}

B - Collecting Packages

题意:有个机器人,只能向上走或者向右走,要从(0,0)经过所有的点(xi,yi),求是否可行,若可行则输出字典序最小的方案。

题解:字典序最小就是说先往右走再往上走。直接把所有点按x排序,要求每个点与(0,0)包围的矩形包含此前的所有点,只需要比前面的点都高就行了。由数学归纳法可知只需要比前一个点高就行了

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
struct node{
	ll x,y;
};
 
int cmp(node a,node b){
	if(a.x==b.x){
		return a.y<b.y;
	}
	return a.x<b.x;	
}
 
int main()
{
	ll q;cin>>q;
	while(q--){
		node libm[1005];	
		ll n;cin>>n;
		ll maxx=0,maxy=0;
		for(int i=1;i<=n;i++){
			cin>>libm[i].x>>libm[i].y;
		}
		int flag=0;
		sort(libm+1,libm+n+1,cmp);
		for(int i=1;i<=n;i++){
			maxx=max(maxx,libm[i].x);
			maxy=max(maxy,libm[i].y);
			if(libm[i].x<maxx||libm[i].y<maxy){
				flag=1;
				break;
			}
		}
		if(flag) cout<<"NO"<<endl;
		else {
			libm[0].x=0;libm[0].y=0;
			cout<<"YES"<<endl;
			for(int i=1;i<=n;i++){
				ll xx=libm[i].x-libm[i-1].x;
				ll yy=libm[i].y-libm[i-1].y;
				for(int i=1;i<=xx;i++){
					cout<<"R";
				}
				for(int i=1;i<=yy;i++){
					cout<<"U";
				}
			}
			cout<<endl;
		}
	}
}

C - Product of Three Numbers

题意:给一个数n,满足n>=2,要求将n分解成互异的三个数a,b,c,使得abc==n,且a,b,c>=2。给出一种分解的方案,或者说明其不存在。
题解:有两种写法,一种是纯暴力,但是注意记录个数(我就在这里爆炸了);还有一种是唯一分解定理的解法

先上暴力:

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int maxn=1e5+5;
bool vis[maxn];
int prime[maxn],cnt=0;
int main()
{
    int q;cin>>q;
    while(q--){
		ll n;cin>>n;
		ll a[5];
		ll cnt=0;
		int flag=0;
		for(int i=2;i<=maxn;i++){
			if(n%i==0){
				n/=i;
				cnt++;
				a[cnt]=i;
			}
			if(i>=n){
				flag=1;
				break;
			}
			if(cnt==2) break;
		}
		if(cnt==0) flag=1;
		if(cnt==1&&n>maxn) flag=1;
		if(flag) cout<<"NO"<<endl;
		else{
			cout<<"YES"<<endl;
			cout<<a[1]<<" "<<a[2]<<" "<<n<<endl;
		}
	}
}

这个是唯一分解定理的解法:

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int maxn=1e5+5;
int p[maxn];
int main()
{
    int q;cin>>q;
    while(q--){
		ll n;cin>>n;
		int cnt=0;
		for(int i=2;i*i<=n;i++){
			while(n%i==0){
				p[++cnt]=i;
				n/=i;	
			}
		}
		if(n!=1) p[++cnt]=n;
		int a=1,b=1,c=1;
		for(int i=1;i<=cnt;i++){
			if(a==1) a*=p[i];
			else if(b==1||a==b) b*=p[i];
			else c*=p[i];
		}
		if(a==1||b==1||c==1||a==b||b==c||a==c)printf("NO\n");
		else printf("YES\n%d %d %d\n",a,b,c);		
	}
}

D - MEX maximizing

题意:有q次操作和一个固定的正整数x,每次操作会往序列中加入一个数字y,你可以在任何时候对序列中的某个y进行任意多次加减x操作(但不能使他们变成负数),求使得整个序列的MEX最大的方案时的MEX的值。

题解:显然模x余数相同的都是同一种等价的东西,可以维护模x值不同结果的cnt。那么MEX操作就相当于询问整个cnt序列中的最小值(这个最小值是一层一层循环叠在下面把MEX垫高),然后再求序列中等于这个最小值的最左边的元素,这个显然可以用线段树来维护(甚至可以支持修改删除)。

但是最简单的操作还是在cnt里面数了之后不断尝试越过MEX即可。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int maxn=4e5+5;
const int INF=0x3f3f3f3f;
ll ans,cnt[maxn];
int main()
{
	ll q,x;cin>>q>>x;
	while(q--){
		ll n;cin>>n;
		cnt[n%x]++;
		while(cnt[ans%x]){
			cnt[ans%x]--;
			ans++;
		}
		cout<<ans<<endl;
	}
}
发布了71 篇原创文章 · 获赞 5 · 访问量 3386

猜你喜欢

转载自blog.csdn.net/Rainfoo/article/details/104075922