BUPT Summer 2020 Combat #1, 2017-2018 8th BSUIR Open Programming Contest. Semifinal

A.BSUIR Open

存下每个字符出现的次数,乘法原理,英语太差了,一开始没看懂题目。。 直接上jn的代码了(

#include <iostream>
#include <cstring>

using namespace std;

int main() {
	char s[1010];
	cin >> s;
	long long BSUIROPEN[20], ans = 1;
	memset(BSUIROPEN, 0, sizeof(BSUIROPEN));
	for (int i = 0; i < strlen(s); i++) {
		char c = s[i];
		if (c == 'B') BSUIROPEN[1]++;
		else if (c == 'S') BSUIROPEN[2]++;
		else if (c == 'U') BSUIROPEN[3]++;
		else if (c == 'I') BSUIROPEN[4]++;
		else if (c == 'R') BSUIROPEN[5]++;
		else if (c == 'O') BSUIROPEN[6]++;
		else if (c == 'P') BSUIROPEN[7]++;
		else if (c == 'E') BSUIROPEN[8]++;
		else if (c == 'N') BSUIROPEN[9]++;
	}
	for (int i = 1; i <= 9; i++) {
		ans *= (BSUIROPEN[i] % (long long)(1e9 + 7));
		ans %= (long long)(1e9 + 7);
	}
	cout << ans;
	return 0;
}

B.Freebie

求数学期望,当星期数是2,3,4,5时,当天有多个人同时过生日的概率是

[1-当天没人过生日的概率-当天只有一个人过生日的概率 ]

如果是6,7,1时,这三天等价,一个人的生日在这段时间内的概率是362/365。
把一年内每天的数学期望加起来即可。

#include<iostream>
#include <string>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
int main() {
	int n = 0;
	cin >> n;
	if (n == 1) {
		printf("0");
		return 0;
	}
	double p1 = 1.0 - pow((double)364 / 365.0, n) - 1 / 365.0 * pow((double)364 / 365.0, n - 1) * n;
	double p2 = 0;
	for (int i = 0; i < 5; i++) {
		if (i == 0) {
			p2+=1.0- pow((double)362 / 365.0, n) - 3 / 365.0 * pow((double)362 / 365.0, n - 1) * n;
		}
		else {
			p2 += 1.0 - pow((double)364 / 365.0, n) - 1 / 365.0 * pow((double)364 / 365.0, n - 1) * n;
		}
	}
	double ans = p1 + p2 * 52;
	printf("%.11f", ans);
}

C.Good subset

异或运算有自反性,因此每个数字只能用一次,我们统计当前队列中0-42的数字的个数,判断每个数字在队列中是否存在。之后搜索用当前存在的数字能否得出42。搜索使用递推,由于数列的数字最大是43,因此能达到的最大值是63,用mk[i]表示运算可以到达i,当前数字是j时,如果mk[i]被标记,那么mk[i^j]也能到达,最后检查mk[42]是否被标记即可。搜索的方式是大师告诉我的 爬了

#include<iostream>
#include <string>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
int mk[64] = {};
int cnt[50] = {};
queue<int>que;
void func() {
	for (int i = 0; i < 64; i++)
		mk[i] = 0;
	mk[0] = 1;
	for (int i = 0; i <= 42; i++) {
		if (cnt[i])
			for (int j = 0; j < 64; j++)
				if (mk[j])
					mk[i ^ j] = 1;
	}
	if (mk[42] == 1)
		cout << "Yes
";
	else
		cout << "No
";
}
int main() {
	int n = 0;
	cin >> n;
	for (int i = 0; i < n; i++) {
		char k;
		cin >> k;
		if (k == '+') {
			int a;
			cin >> a;
			que.push(a);
			cnt[a]++;
		}
		else {
			cnt[que.front()]--;
			que.pop();
		}
		func();
	}
}

F.The closest subsequence

排序后二分,搜索大于等于给定数的第一个数,比较这个数和它前面那个数与给定数的距离,取近的为中位数,距离相等则比较数字在整个数列中的位置,取能令结果更长的。
题目要求输出的是数在原数列的编号(

#include<iostream>
#include <string>
#include<vector>
#include<algorithm>
using namespace std;
struct my
{
	long long a=0;
	int id=0;
	bool operator< (const my b)const {
		return a < b.a;
	}
	bool operator== (const my b)const {
		return a == b.a;
	}
};
bool cmp(my a, my b) {
	return a.a < b.a;
}
vector<my> dat;
vector<long long> ans;
long long n, k;
int main() {
	cin >> n>>k;
	for (int i = 0; i < n; i++) {
		my temp;
		cin >> temp.a;
		temp.id = i + 1;
		dat.push_back(temp);
	}
	my temp;
	temp.a = k;
	sort(dat.begin(), dat.end(),cmp);
	vector<my>::iterator kk=lower_bound(dat.begin(), dat.end(), temp);
	if (kk == dat.end())kk--;
	long long k1 = kk->a - k;
	long long  k2 = 0x3f3f3f3f;
	if (kk != dat.begin())
		k2 = k - (kk - 1)->a;
	if (k2 < k1)
		kk--;
	long long l, r;
	l = kk - dat.begin();
	r = (long long)(dat.end() - kk) - 1;
	if (k2 == k1) {
		if (l > r) {
			kk--;
			l = kk - dat.begin();
			r = (long long)(dat.end() - kk) - 1;
		}
	}
	if (l >= r) {
		for (vector<my>::iterator i = kk - r; i != kk + r + 1; i++) {
			ans.push_back(i->id);
		}
	}
	else
	{
		for (vector<my>::iterator i = kk - l; i != kk + l + 2; i++) {
			ans.push_back(i->id);
		}
	}
	cout << ans.size()<<'
';
	for (auto i = ans.begin(); i != ans.end(); i++)
		cout << *i<<' ';
}

H.Large and even

等差数列,一开始没用longlong还挂了。。

#include<iostream>
#include <string>
#include<vector>
using namespace std;
long long ans = 0, n = 0;
int main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		long long l, r;
		cin >> l >> r;
		if (l & 1)l++;
		if (r & 1)r--;
		ans = (l + r) * ((r - l) / 2 + 1) / 2;
		if (l > r)
			cout << 0 << '
';
		else
		cout << maxa << '
';
	}
}

J.Vova, who doesn't know

异或运算有交换律,直接输出1到n就彳亍。。。结果我这个弱智打了个搜索(

#include<iostream>
#include <string>
#include<vector>
using namespace std;
long long ans = 0, n = 0;
int main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin>>ans;
                cout<<i+1<<' ';
	}
}
K-ON!!
原文地址:https://www.cnblogs.com/pophirasawa/p/13270273.html