Codeforces Global Round 24(11.28 补题)

Dashboard - Codeforces Global Round 24 - Codeforces

A. Doremy's Paint

题意:给定一个长度为n的序列,定义 c(l,r)为 l~r 之间不同的序列的个数,确定一组 l,r 使得

l-r-c(l,r) 的值最大

思路:可以发现当多加一个数时并不会影响答案的大小(如l-- 或r++ ,l-r减小或增大的同时,c(l,r) 会同步 增大或减小),故让l,r之间的相同的数的个数尽可能的大即可,也就是输出1,n即可。

#include<bits/stdc++.h>
// #define int long long
#define PII pair<int,int> 
#define ios ios::sync_with_wtdio(false);cin.tie(0);cin.tie(0)

using namespace std;

const int N=1e5+10;
int a[N];
int n;

void solve(){
	cin >> n;
	for(int i=0;i<n;i++) cin >> a[i];
	cout << "1 n" << endl;
}

int main(){
	int t=1;
	cin >> t;
	while(t--){
		solve();
	}
	return 0;
}

B. Doremy's Perfect Math Class

题意:给定一个大小为n的集合(不含有重复元素),我们可以选定集合中的两个元素做差,将差加入集合中,问集合中的数最多有多少个

思路:猜结论,如若一组数的gcd为1,那么max{1...n}中的任意一个数都可以构造出来,如({16,6},gcd=2,16-6=8,8-6=2,则可构造出{2,4,6,8,10,12,14,16})。一个集合能构造出的数就是集合内最大的值除gcd,如(gcd为3 {3,6,.....,max})。

故结论为                    ans=\frac{max}{gcd}

#include<bits/stdc++.h>
// #define int long long
#define PII pair<int,int> 
#define ios ios::sync_with_wtdio(false);cin.tie(0);cin.tie(0)

using namespace std;

const int N=1e5+10;
int a[N];
int n,m;

void solve(){
	cin >> n;
	int res=0;
	int mx=0;
	for(int i=0;i<n;i++){
		cin >> a[i];
		mx=max(mx,a[i]);
		res=__gcd(res,a[i]);
	}
	cout << mx/res << endl;
}

int main(){
	int t=1;
	cin >> t;
	while(t--){
		solve();
	}
	return 0;
}

C. Doremy's City Construction

题意:给定n个带权点,在点中添加若干条无向边,使得途中不存在连续非下降的路径(即连续非下降的路径大于等于3不符合)

思路:将点的依据权排序之后,可以将点分为两个集合,小点集合和大点集合,集合中的每一个点都可以连接另一个集合中的所有点,故可以枚举两个集合的边界,取最大值即可。

#include<bits/stdc++.h>
#define int long long
#define PII pair<int,int> 
#define ios ios::sync_with_wtdio(false);cin.tie(0);cin.tie(0)

using namespace std;

const int N=2e5+10;
int a[N];
int n;

void solve(){
	cin >> n;
	map<int,int> mp;
	for(int i=0;i<n;i++){
		cin >> a[i];
		mp[a[i]]++;
	}
	sort(a,a+n);
	if(a[0]==a[n-1]){
		cout << n/2 << endl;
		return ;
	}
	int ans=0,num=0;
	for(int i=0;i<n;i+=mp[a[i]]){
		num+=mp[a[i]];
		ans=max(ans,num*(n-num));
	}
	cout << ans << endl;
}

signed main(){
	int t=1;
	cin >> t;
	while(t--){
		solve();
	}
	return 0;
}

D:D. Doremy's Pegging Game(理解不了,贴个题解)

题意:存在 n 个点的钉子,绕成一个环。其中环内部有一个特殊的钉子,这个钉子比环上的钉子都要短。刚开始一个橡皮绳绕在环上,每次可以取走一个环上的钉子。钉子被取走后橡皮筋会收缩。一旦其中一个点被挂在了中间特殊的钉子上,游戏结束。求删除序列的方案数。

思路:

#include<bits/stdc++.h>
#define LL long long 
using namespace std;

const int MX = 5000 + 233;
LL C[MX][MX] ,n ,p ,fac[MX];

void init(){
	for(int i = 0 ; i < MX ; ++i) C[i][0] = 1;
	for(int i = 1 ; i < MX ; ++i)
		for(int j = 1 ; j < MX ; ++j)
			C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % p;
	fac[0] = fac[1] = 1 % p;
	for(int i = 2 ; i < MX ; ++i) fac[i] = fac[i - 1] * i % p;
}

int main(){
	cin >> n >> p;
	init();
	int t = n / 2;
	LL Ans = 0;
	for(int i = t ; i <= n - 1 ; ++i){
		if((n & 1) && i == n - 1) break;
		int upper = (i == n - 1) ? n - i - 1 : n - i - 2;
		for(int j = 0 ; j <= upper ; ++j){
			Ans = (Ans + n * (2 * t - i) * C[upper][j] % p * fac[j + i - 1]) % p;
		}
	}
	cout << Ans << endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值