湖南工学院2021级ACM正式队员第五次周测题解

本场 3 题及格,4题良好,5-6题优秀。

A题语文

来源:Educational Codeforces Round 129 (Rated for Div. 2), problem: (B) Card Trick

考察:思维

难度:红题

由于每次操作并未改变移动区间中间的顺序,因此实际上每 n 本移动就恢复到了原状,因此直接加和对 n 取余即可。

标程如下

#include<bits/stdc++.h>
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 998244353;
using namespace std;
int a[202020], b[202020];
int main() {
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		for(int i = 1;i <= n;i++){
			cin >> a[i];
		} 
		int m;
		cin >> m;
		ll sum = 0;
		for(int i = 1;i <= m;i++){
			cin >> b[i];
			sum += b[i];
		}
		sum %= n;
		cout << a[1 + sum] << endl;
	}
	return 0;
}

B题数学

来源:第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海站)G题 Fibonacci

考察:思维

难度:橙题

我们可以通过观察斐波那契数列的规律可知,一定会遵循 奇 奇 偶 奇 奇 偶 奇 奇 偶 奇 奇 偶....的规律。而我们知道 奇数 * 奇数 = 奇数,奇数 * 偶数 = 偶数,偶数 * 偶数 = 偶数,因此我们实际上答案就跟斐波那契数列中偶数出现个数有关。因此我们需要先算出范围 n 内一共有多少个偶数,对于每个偶数它可以创造出 n - 1 的价值,于是答案就是 偶数个数 * (n - 1),那你就 wa 了,因为每个偶数创造出的价值可能会重复,比如 奇 奇 偶 奇 奇 偶 奇,第一个偶数创造了 6 的价值,因为他会跟除他以外的所有数相乘。但是当我们计算第二个偶数的时候,若依然按照以上公式,则会造成第二个偶数再次跟第一个偶数相乘,从而多出了一个答案,因此,我们算完总价值之后需要减去重复的价值,而重复的答案价值实际上就是  eq?%5Csum_%7Bi%3D1%7D%5En%5Csum_%7Bj%3Di&plus;1%7D%5En 的种类数为 n * (n - 1) / 2。因此我们设 x 为偶数个数,则答案为 x * (n - 1) - x * (x - 1) / 2。注意开 long long。

标程如下

#include<bits/stdc++.h>
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 998244353;
using namespace std;
int main() {
	int t;
    cin >> t;
    while(t--){
        ll n;
	    cin >> n;
	    ll x = n / 3;
	    cout << x * (n - 1) - x * (x - 1) / 2 << endl;
    }
	return 0;
}

C题物理

来源:Codeforces Round #785 (Div. 2), problem: (C) Palindrome Basis

考察:dp,数学

难度:黄题

本题为完全背包方案数模板题【动态规划】完全背包:整数划分(方案数)_暮色_年华的博客-优快云博客_背包问题整数规划,唯一的区别在于要先将回文数筛出来,其他的跟完全背包方案数求法完全一致。另外因为 t 比较大,所以打个表,否则可能会超时。

标程如下

#include<bits/stdc++.h>
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 1e9+7;
using namespace std;
int pali[100000];
int cnt = 0;
void pre(){
	for(int i =1;i<=40000;i++){
		int temp = 0;
		int x = i;
		while(x){
			int y = x%10;
			temp=temp*10+y;
			x/=10;
		}
		if(temp==i){
			pali[++cnt] = i;
			//cout << i <<endl;
		}
	}
	//cout <<cnt<<endl;
}
ll dp[50000];
ll ans[50000];
void pre1(){
	memset(dp,0,sizeof(dp));
    dp[0] =1;
	for(int i =1;i<=cnt;i++){
		for(int j = pali[i];j<=40000;j++){
			dp[j]+=dp[j-pali[i]];
			dp[j]%=mod;
		}
	}
}
int main() {
    int t;
    cin >> t;
    pre();
    pre1();
    while(t--){
    	ll n;
    	cin >> n;
		cout << dp[n]%mod<<endl;
	}
	return 0;
}

D题英语

来源:Educational Codeforces Round 129 (Rated for Div. 2), problem: (D) Required Length

考察:bfs

难度:黄题

bfs 板子稍改题,因为 n 最大为 19,而每次若乘 1,则最多乘 1 次就筛掉了,若乘 2,最多乘 18 次左右,因此数据范围比较小,可以直接 bfs

标程如下

#include<bits/stdc++.h>
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 998244353;
using namespace std;
ll n,x;
ll q[30];
void bfs(){
	queue<ll> s;
	s.push(x);
	map<ll,int> vis;
	map<ll,int> dis;
	int qq = -1;
	while(!s.empty()){
		ll a = s.front();
		s.pop();
		vis[a] = 1;
		int ans = 0;
		ll temp = a;
		while(temp){
			ans++;
			q[ans] = temp%10;
			temp/=10;
		}
		if(ans == n){
			qq = dis[a];
			break;
		}
		for(int i = 1;i<=ans;i++){
			ll b = q[i]*a;
			if(!vis[b]){
				vis[b] =1;
				s.push(b);
				dis[b] = dis[a] +1;
			}
		}
	}
	cout << qq;
}
int main() {
	cin >> n>>x;
	bfs();
	return 0;
}

E题化学

来源:无

考察:签到

难度:红题

可以发现给出的三种氨基酸都有氨基和羧基,无论哪两个反应,都会去除 18 的相对分子质量,因此直接算出总相对分子质量再减去脱去的水分子即可。

标程如下

#include<bits/stdc++.h>
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 998244353;
using namespace std;
int main() {
	int n;
	cin >> n;
	int x = 0, y = 0, z = 0;
	for (int i = 1; i <= n; i++) {
		string a;
		cin >> a;
		if (a == "Ala") {
			x++;
		}
		else if (a == "Gly") {
			y++;
		}
		else {
			z++;
		}
	}
	if (n == 1) {
		cout << 0;
	}
	else {
		cout << n - 1 << " ";
		cout << x * 89 + y * 75 + z * 105 - 18 * (n - 1);
	}
	return 0;
}

F题生物

来源:Codeforces Round #794 (Div. 2), problem: (A) Everything Everywhere All But One

考察:思维

难度:橙题

想要实现要求,那么必须平均数在数组中存在一次,且平均数为整数,这样的话剩余的 n - 1 个数无论如何都能变成平均数。

标程如下

#include<bits/stdc++.h>
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 998244353;
using namespace std;
int vis[200];
int main() {
	int t;
	cin >> t;
	while (t--) {
		memset(vis, 0, sizeof(vis));
		int n;
		cin >> n;
		int sum = 0;
		for (int i = 1; i <= n; i++) {
			int x;
			cin >> x;
			sum += x;
			vis[x] = 1;
		}
		if (!fmod(1.0 * sum / n, 1)) {
			if (vis[sum / n]) {
				cout << "YES" << endl;
			}
			else {
				cout << "NO" << endl;
			}
		}
		else {
			cout << "NO" << endl;
		}
	}
	return 0;
}
 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值