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;
}

浙公网安备 33010602011771号