补题日记2018 CCPC桂林站

Posted cls1277

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了补题日记2018 CCPC桂林站相关的知识,希望对你有一定的参考价值。

Pro

2018 China Collegiate Programming Contest - Guilin Site

Sol

A. Array Merge

贪心,如果没有顺序的限制,数字大的越靠前越优,而现在有顺序,所以把前i个元素综合考虑。

设前i个元素的平均值为a,则当新的值A[i+1]放进来的时候,判断A[i+1]最远能合并到哪,就把A[i+1]与放到该集合。

为什么扯到合并和集合了呢?因为这个题目本质上与不考虑位置时差不多,就是先分组然后A,B两个分完之后的集合分别看先放哪个最优。

写的时候遇到了一个问题,对2 1 5 2分组的时候,可能会把1和5分到一组,但其实把2 1 5放到一起会更好,因为会让平均值更大,注意这个地方就可以了。

D. Bits Reverse

可以发现,交换三位数字其实就是交换奇数位置或者偶数位置上的数字。

所以,如果x和y的奇数位或者偶数位的数字个数不同,答案为-1。其他情况为查询x中奇(偶)出现的位置与y中奇(偶)出现的位置。

二者位置差值除以二的求和就是答案。

G. Greatest Common Divisor

类似于更相减损,排序去重后,然后判断a[1]+k,与a[2]-a[1],a[3]-a[2],a[4]-a[3]等的gcd是否大于1

因为k是要求的值,所以分以下几种情况:

1.后面几个数字(除a[1]+k之外的数字,下同)的gcd=1,总的gcd一定等于1

2.gcd!=1,则可以通过枚举gcd的因子求得最小的k(具体看代码最后部分)

J. Stone Game

贪心,容易想到判断尽可能拿走的数目的奇偶性。

尽可能拿走的数目就是排序之后分几种情况累加的结果。从小到大排序后,依次修改每一个点。

对于i点,如果两边都比它的值大,那么这个点可以被完全拿走。

如果两边都比它的值小,那么这个点就可以被拿成左右两端最大值加1。

如果两边一个大一个小,那么这个点就可以被拿成左右两端最小值加1。

(特意用了排比句ovo)

Code

A. Array Merge

//By cls1277
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<sstream>
#include<set>
#include<cassert>
#include<bitset>
using namespace std;
typedef long long LL;
#define PI acos(-1)
#define INF 2147483647
#define eps 1e-7
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define lowbit(_) _&(-_)
#define mk(_,__) make_pair(_,__)
#define pii pair<LL,LL>
#include <fstream>
#define ls x<<1
#define rs x<<1|1
#define endl '\\n'
inline LL read() {
	LL x = 0, f = 1;char c = getchar();
	while (!isdigit(c)) { if (c == '-')f = -f;c = getchar(); }
	while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48ll), c = getchar();
	return x * f;
}

const LL maxn = 1e5+5;
LL n,m,a[maxn],b[maxn],p1,p2,l1,l2,tt,res,f1,f2;
vector<LL>ans;
struct Node {
	LL sum,cnt;
	Node(){};
	Node(LL ss , LL cc) {
		sum=ss , cnt=cc;
	}
	bool operator < (const Node &tmp) {
		return sum*tmp.cnt<cnt*tmp.sum;
	}
	Node operator + (const Node &tmp) {
		return Node(sum+tmp.sum,cnt+tmp.cnt);
	}
};
Node va[maxn],vb[maxn];

int main() {
	ios::sync_with_stdio(false);
	#ifdef DEBUG
	freopen("data.txt","r",stdin);
	#endif
	LL T; cin>>T;
	while(T--) {
		cout<<"Case "<<(++tt)<<": ";
		ans.clear();
		p1=p2=0; res=0;
		cin>>n>>m;
		Fo(i,1,n) cin>>a[i];
		Fo(i,1,m) cin>>b[i];
		Fo(i,1,n) {
			va[++p1] = Node(a[i],1);
			while(p1>1&&va[p1-1]<va[p1]) {
				va[p1-1] = va[p1-1]+va[p1];
				p1--;
			}
		}
		Fo(i,1,m) {
			vb[++p2] = Node(b[i],1);
			while(p2>1&&vb[p2-1]<vb[p2]) {
				vb[p2-1] = vb[p2-1]+vb[p2];
				p2--;
			}
		}
		va[++p1]=vb[++p2]=Node(-INF,1);
		//Fo(i,1,p1) cout<<va[i].sum<<" "<<va[i].cnt<<endl;
		//Fo(i,1,p2) cout<<vb[i].sum<<" "<<vb[i].cnt<<endl;
		l1=l2=1; f1=f2=1;
		while(f1<p1 || f2<p2) {
			if(va[f1]<vb[f2]) {
				for(LL i=l1; i<=l1+vb[f2].cnt-1; i++)
					ans.push_back(b[i]);
				l1+=vb[f2].cnt;
				f2++;
			} else {
				for(LL i=l2; i<=l2+va[f1].cnt-1; i++)
					ans.push_back(a[i]);
				l2+=va[f1].cnt;
				f1++;
			}
		}
		Fo(i,1,n+m)
			res+=i*ans[i-1];
		cout<<res<<endl;
	}
	return 0;
}

D. Bits Reverse

//By cls1277
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<sstream>
#include<set>
#include<cassert>
#include<bitset>
using namespace std;
typedef long long LL;
#define PI acos(-1)
#define INF 2147483647
#define eps 1e-7
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define lowbit(_) _&(-_)
#define mk(_,__) make_pair(_,__)
#define pii pair<int,int>
#define ls x<<1
#define rs x<<1|1
#define endl '\\n'
inline LL read() {
	LL x = 0, f = 1;char c = getchar();
	while (!isdigit(c)) { if (c == '-')f = -f;c = getchar(); }
	while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48ll), c = getchar();
	return x * f;
}

const LL maxn = 60;
LL a[maxn],b[maxn],p,f1,f2,c[maxn],d[maxn],ans,x,y,tt;

int main() {
	ios::sync_with_stdio(false);
	#ifdef DEBUG
	freopen("data.txt","r",stdin);
	#endif
	int T; cin>>T;
	while(T--) {
		cout<<"Case "<<(++tt)<<": ";
		ans=0;
		Ms(a,0); Ms(b,0);
		cin>>x>>y;
		p=0;
		while(x) {
			a[p++] = x%2;
			x/=2;
		}
		p=0;
		while(y) {
			b[p++] = y%2;
			y/=2;
		}
		f1=f2=0;
		for(int i=59; i>=0; i-=2) {
			if(a[i]) c[f1++]=i;
			if(b[i]) d[f2++]=i;
		}
		if(f1!=f2) {
			cout<<"-1"<<endl;
			continue;
		}
		for(int i=0; i<f1; i++)
			ans+=abs(d[i]-c[i])/2;
		f1=f2=0;
		for(int i=58; i>=0; i-=2) {
			if(a[i]) c[f1++]=i;
			if(b[i]) d[f2++]=i;
		}
		if(f1!=f2) {
			cout<<"-1"<<endl;
			continue;
		}
		for(int i=0; i<f1; i++)
			ans+=abs(d[i]-c[i])/2;
		cout<<ans<<endl;
	}
	return 0;
}

G. Greatest Common Divisor

//By cls1277
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<sstream>
#include<set>
#include<cassert>
#include<bitset>
using namespace std;
typedef long long LL;
#define PI acos(-1)
#define INF 2147483647
#define eps 1e-7
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define lowbit(_) _&(-_)
#define mk(_,__) make_pair(_,__)
#define pii pair<int,int>
#define ls x<<1
2021第7届中国大学生程序设计竞赛CCPC桂林站, 签到题5题

2018 CCPC 桂林站(upc复现赛)总结

2018 CCPC 吉林站 H Lovers

CCPC2018 桂林 A: Array Merge(贪心带权并查集合并)

22年ccpc桂林站记录

22年ccpc桂林站记录