Codeforces 1600 x 5 (1)

A.点我跳转

107B Basketball Team

tag:期望,dp,数论,排列组合

题意

yft所在的学校有 \(m\) 个社团,他所在的社团编号是 \(h\) 。现在yft受wjx命令需要从这 \(m\) 个社团中随机挑出 \(n\) 个人(\(n\) 个人包括他自己),请问挑出的人存在和yft同社团的概率是多大。

问题转化为,从\(m\)个盒子中取\(n\)个球,在取了\(h\)盒中的一个球的条件下,\(h\)盒还取了别的球的概率

解题思路

正难则反,可以从没选中这个方面出发,循环时,取走一颗不是\(a[h]\)的人。

过题代码

#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N = 2e5 + 10, MOD = 1e9+7, inf = 0x3f3f3f3f;
int a[N];
signed main()
{
	int n,m,h,sum = 0;
	cin >> n >> m >> h;
	for (int i = 1;i <= m; i++)
	{
		cin >> a[i];
		sum += a[i];
	}
	if (sum < n) return cout << "-1\n", 0;
	double ans = 1;
	double x = sum - a[h], y = sum - 1;
	for (int i = 1; i < n; i++)          // 选n - 1次
	{
		ans *= x / y;
		x--;
		y--;
	}
	cout.precision(10);
	cout << fixed << 1.0 - ans << '\n';
    return 0;
}

B.点我跳转

453A Little Pony and Expected Maximum

tag. 期望

题意

色子有m面,甩n次,求期望值。

过题代码

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

const int N = 2e5 + 10, MOD = 1e9+7, inf = 0x3f3f3f3f;

signed main()
{
	double n,m,ans;
	cin >> m >> n;
	for (int i = 1;i <= m; i++)
	{
		ans += i * 1.0 * (pow(i/m , n) - pow((i - 1)/m , n));  // 乘i可以理解为转到[1,i]区间的概率期望
	}
	cout.precision(12);
	cout << fixed << ans << "\n";
    return 0;
}

C.点我跳转

930 B. Game with String

tag. 期望,string

过题代码

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

const int N = 5e3 + 10, MOD = 1e9+7, inf = 0x3f3f3f3f;
char str[N << 1];
int a[26][26][N];
signed main()
{
	cin >> str + 1;
	int n = strlen(str + 1);
	for (int i = 1; i <= n; i++) str[i + n] = str[i];
	for (int i = 1; i <= n; i++)
		for (int j = i + 1; j < i + n; j++)
		{
			a[str[i] - 'a'][str[j] - 'a'][j - i + 1]++;
		}
	int tot = 0;
	for (int i = 0; i < 26; i++){
		int tmp = 0;                                          
		for (int j = 1; j <= n; j++)
		{
			int sum = 0; 
			for (int k = 0; k < 26; k++)
				if (a[i][k][j] == 1) sum++;  //i开头往后j长度是第k个字母且唯一时,sum++ 
			tmp = max(sum,tmp);     //i开头,选择某个长度,使得可以推出的字母数最多
		}
		tot += tmp;    //i开头的答案累计
	}
	cout.precision(12);
	cout << fixed << tot * 1.0 / n << '\n';
    return 0;
}

D.点我跳转

597 B. Restaurant

tag. 贪心,排序

题意

给n个点对,每个点对为一个区间,在n个区间里选出最多的区间,所有区间不相交,输出能选出的最大数量

过题代码

#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second

using namespace std;
typedef pair<int, int> pii;

const int N = 5e5 + 10, MOD = 1e9+7, inf = 0x3f3f3f3f;
pii a[N];
bool cmp(pii A, pii B)
{
	return A.se < B.se;
}
signed main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i].fi >> a[i].se;
	sort(a+1,a+1+n,cmp);
	int tmp = a[1].se;
	int ans = 1;
	for (int i = 2; i <= n; i++){
		if (tmp < a[i].fi){
			tmp = a[i].se;
			ans++;
		}
	}
	cout << ans << '\n';
    return 0;
}

E.点我跳转

28 B. pSort

tag. dsu

题意

给一个序列\(a\),a序列元素不重复且从1到len(a),再给一个序列\(b\),问能否通过在a序列中的交换,使a序列变为有序从1到n。
交换条件:序列b_i代表当前位置i的距离b_i的元素a_{i+b_i}可以任意交换

解题思路

可以联通的话代表可以随意互换,那么使用并查集即可判断。

过题代码

#include<bits/stdc++.h>
using namespace std;
const int N = 2e2;
int a[N], b[N], fa[N];
int find(int x){
	if (x == fa[x]) return x;
	return fa[x] = find(fa[x]);
}
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];
	for (int i = 1; i <= n; i++) cin >> b[i];
	for (int i = 1; i <= n; i++) fa[i] = i;
	for (int i = 1; i <= n; i++){
		if (i + b[i] <= n || i - b[i] >= 1){
			int x = find(i);
			if (i + b[i] <= n){
				int y = find(i + b[i]);
				if (x != y){
					fa[y] = x;
				}
			}
			if (i - b[i] >= 1){
				int y = find(i - b[i]);
				if (x != y){
					fa[y] = x;
				}
			}
		}
	}
	int ok = 1;
	for (int i = 1; i <= n; i++){
		int x = find(a[i]);
		int y = find(i);
		if (x != y){
			ok = 0;
			break;
		}
	}
	if (ok) cout << "YES\n";
	else cout << "NO\n";
	return 0;
}
posted @ 2020-10-31 19:34  SZyzBO  阅读(57)  评论(0)    收藏  举报