【CF】Good Bye 2018

Happy New Year! CF GoodBye2018 官方题解 只做出来前4道,被E题搞自闭之后就睡了orz. A题:水题,不想说题意orz
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a,b,c;
int main() {
	cin>>a>>b>>c;
	a = min(a,min(b-1,c-2));
	b = min(b,min(a+1,c-1));
	c = min(c,min(a+2,b+1));
	a = max(a,0); b = max(b,0); c = max(c,0);
	cout<<a+b+c<<endl;
}
B题 给你n个A类型点和n个B类点,两两匹配,保证可以找到一个点满足对于所有匹配有(ax+bx,ay+by)。 根据数据观察发现直接所有的横坐标加起来/n,所有纵坐标加起来/n就可以了。(人生第一次被hack  orz orz orz 没开long long orz orz  orz )
#include<iostream>
#include<cstdio>
#define int long long 
using namespace std;

int n;
int X,Y;
main() {
	cin>>n;
	for(int i=1;i<=2*n;i++) {
		int x,y; cin>>x>>y;
		X+=x; Y+=y;
	}
	X/=n; Y/=n;
	cout<<X<<' '<<Y<<endl;
}
  C题 编号1-n, 球开始在1手上,顺时针(编号变大)选择扔一个距离k(小于n)(之后固定不变),又一直转,直到又到1手上.这样一次的权值为转一圈所有人的编号总和.求出所有的可能编号总和,n1e9. 随便找几个数看一下规律,我们发现,和n的因子有关系,枚举一下因子就出来了.
#include<stdio.h>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;
int n;
int st[maxn],tot;
main() {
	cin>>n;
	int sq = sqrt(n);
	for(int i=1;i<=sq;i++) {
		if(n%i==0) {
			int xs = n/i; int o = i;
			st[++tot] = 1ll*(2+(xs-1)*o)*xs/2;
			if(i*i!=n) {
				o = n/i; xs = i;
				st[++tot] = 1ll*(2+(xs-1)*o)*xs/2;
			}
		}
	}
	sort(st+1,st+1+tot);
	tot = unique(st+1,st+1+tot)-st-1;
	for(int i=1;i<=tot;i++) cout<<st[i]<<' ';
}
D题 考试的时候找规律出来的,,发现减去n!之后有规律.官方题解..也没怎么看懂,以后再搞懂吧orzorzorz
#include<stdio.h>
#include<iostream>
using namespace std;
const int mod = 998244353;
int add(int x,int y) { x+=y; return x>=mod?x-mod:x; }
int sub(int x,int y) { x-=y; return x>=mod?x+mod:x; }
int mul(int x,int y) { return 1ll*x*y%mod; }
int jc,now;
int main() {
	now = 1; jc = 1;
	int n; cin>>n;
	if(n==1) { puts("1"); return 0; }
	for(int i=2;i<=n;i++) {
		jc = mul(jc,i);
		now = add( mul(sub(now,1),i) , jc);
	}
	cout<<now;
}
E 题,给出n个点的度数,你给出第n+1个点的度数的所有可能性使得这张图为简单无向图。 由于握手引理,对于无向图的度数为奇数的点个数为偶个,那么我们可以得到最后答案的奇偶。然后就按大到小排序,然后从大的开始,减去大的所有度数往后面的点全部删一个度数,如果不够删看n+1点能不能补完,以及至少可以补多少和最多连多少。 之后得到上下界之后依次+2就可以了,实现利用二分。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define int long long
using namespace std;
const int maxn = 5e5+5;
int n;int top;
int a[maxn],sm[maxn];
main() {
	int orz = 0;
	scanf("%I64d",&n);
	for(int i=1;i<=n;i++) {
		int x; scanf("%I64d",&x);
		if(x) a[++top] = x;
		orz = (orz+x)&1;
	}
	n = top; sort(a+1,a+1+n,greater<int>());
	for(int i=1;i<=n;i++) sm[i] = sm[i-1] + a[i];
	int L = 0; int R = n;
	for(int i=1;i<=n;i++) {
		int j = lower_bound(a+i+1,a+1+n,i,greater<int>())-a;
		int a = sm[i]; int b = (j-i-1)*i + sm[n] - sm[j-1] + i*(i-1);
		if(a>b) {
			if(a-b-i>0) { puts("-1"); exit(0); } 
			else L = max(L,a-b);
		}
		R = min(R,j-(a-b-i));
	//	cout<<j<<endl;
	}
	if(orz) {
		if(!(L&1)) L++;
		if(!(R&1)) R--;
	} else {
		if(L&1) L++;
		if(R&1) R--;
	}
	bool fl = 0;
	for(int i=L;i<=R;i+=2) printf("%I64d ",i),fl = 1;
	if(!fl) puts("-1");
}
F题,在一条路上有陆地、水域和岩浆三种地形,用走5s/m(只能在陆上走),用游3s/m(只能在水上飞),用飞1s/m,飞1s需要1能量,每走一m或者游一m得到1能量,求花费最少时间走到终点。 考虑贪心就好(然而E题卡自闭后考场上思维僵化+想睡觉orz),如果遇到岩浆,肯定要飞过去,如果不能飞过去只能回走0.5m然后又走0.5m攒能量,那么优先攒能量地在水上。而对于最后可能剩下能量的情况肯定是浪费,那么除了岩浆以外,优先选择在陆地的地方飞行,那么考虑陆地花费的能量既不能超过攒的能量的1/2(因为飞花了1能量也少得了一能量),也不能超过陆地走的长度。
#include<cstdio>
#include<algorithm>
#include<iostream>
#define int long long
using namespace std;
const int maxn = 2e5+5;
int n;
int nl,tgra;
int a[maxn];
char ss[maxn];
int tim;
main() {
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	scanf("%s",&ss[1]);
	bool flag = 0;
	for(int i=1;i<=n;i++) {
		if(ss[i]=='L') {
			tim += a[i];
			nl -= a[i];
			if(nl<0)  {
				tim += (-nl)*(flag?3:5);
				nl = 0;
			}
		} else if(ss[i]=='W') {
			flag = 1;
			nl += a[i];
			tim += 3*a[i];
		} else {
			nl += a[i];
			tgra += 2*a[i];
			tim += 5*a[i];
		}
		tgra = min(tgra,nl);
	}
	if(nl>0) {
		tim -= (5-1)*tgra/2;
		tim -= (3-1)*(nl - tgra)/2;
	}
	cout<<tim;
}
   
posted @ 2018-12-31 13:37  Newuser233  阅读(5)  评论(0)    收藏  举报