【Codeforces】Codeforces Round #680 Div2

https://codeforces.com/contest/1445

赛时结果

image.png


A. Array Rearrangment

一手纯模拟,没有细节问题。

#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
using namespace std;
const int N=59;

inline int read() {
    register int x=0, f=1; register char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-48,c=getchar();}
    return x*f;
}

int T,n,x,a[N],b[N];

signed main() {
	T=read();
	while(T--) {
		n=read(), x=read();
		rep(i,1,n) a[i]=read();
		rep(i,1,n) b[i]=read();
		sort(a+1,a+n+1);
		sort(b+1,b+n+1); reverse(b+1,b+n+1);
		bool ans=1;
		rep(i,1,n) if(a[i]+b[i]>x) ans=0;
		if(ans==1) puts("YES");
		else puts("NO");
	}
	return 0;
} 

B. Elimination

我比较想吐槽的一道题。纯粹阅读+结论,没什么特别大的意思。答案就是 \(max(a+b,c+d)\)

C. Division

相比于 B 和 D,C 就有意思多了。考虑将 \(q\) 质因数分解。然后由于 \(q\) 不能是 \(x\) 的约数,于是我们需要选择一个 \(q\) 的质因数,然后将 \(p\) 一直除以这个质因数直到 \(p\bmod q\neq 0\)

#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
using namespace std;
const int N=59;

inline int read() {
    register int x=0, f=1; register char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-48,c=getchar();}
    return x*f;
}

int T,p,q;

signed main() {
	T=read();
	while(T--) {
		p=read(), q=read();
		if(p<q) printf("%lld\n",p);
		else if(p%q!=0) printf("%lld\n",p);
		else {
			int ans=1;
			for(int i=2;i*i<=q;i++) {
				if(q%i==0) {
					int t=p;
					while(t%q==0) t/=i;
					ans=max(ans,t);
					while(q%i==0) q/=i;
				}
			}
			if(q!=1) {
				while(p%q==0) p/=q;
				ans=max(ans,p);
			}
			printf("%lld\n",ans);
		}
	}
	return 0;
} 

D. D. Divide and Sum

又是一道结论题。对于数列 \(a\)\(f(p,q)\) 永远是相等的。于是用一个组合数加上稍微模拟一下即可。

#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
using namespace std;
const int N=300009, mod=998244353;

inline int read() {
    register int x=0, f=1; register char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-48,c=getchar();}
    return x*f;
}

int n,a[N];

int mn,fac[N], inv[N], ifac[N];
void pre() {
    inv[0]=inv[1]=fac[0]=ifac[0]=1;
    for(int i=1;i<=mn;i++) fac[i]=fac[i-1]*i%mod;
    for(int i=2;i<=mn;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod;
    for(int i=1;i<=mn;i++) ifac[i]=ifac[i-1]*inv[i]%mod;
}
int C(int x,int y) {
    if(x<0||y<0||x<y) return 0;
    else return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}

signed main() {
	n=read();
	rep(i,1,2*n) a[i]=read();
	sort(a+1,a+2*n+1);
	int ans=0;
	rep(i,1,n) (ans+=abs(a[2*n-i+1]-a[i]))%=mod;
	mn=2*n;
	pre();
	ans=ans*C(2*n,n)%mod;
	printf("%lld\n",ans);
	return 0;
}

E. Team-Building

感觉 D 和 E 的 difficulty gap 比较大。一道有意思的图论题。做法比较烦。

首先对于每一个学术小组,我们都检查一下是不是二分图,如果不是那么就不可能被选做参与活动的组。

我们设 \(c_i\) 代表 \(i\) 所属于的学术小组,\(f(i)\) 表示 \(i\) 在哪个连通块。于是对于两个学术小组,要判断两个是否是二分图,只需要连两个学术小组的连通块即可。那么时间还是 \(O(n^2)\) 的嘛?显然不是,因为最多有 \(O(m)\) 对学术小组是有边的。所以其实是 \(O(m)\)

代码太烦了,以后回来再看看吧。

扔两个题解 https://www.cnblogs.com/George1123/p/13912680.html https://www.luogu.com.cn/blog/SSerxhs/solution-cf1444c

posted @ 2020-11-02 09:22  LarsWerner  阅读(302)  评论(4编辑  收藏  举报