本场 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 的价值,因为他会跟除他以外的所有数相乘。但是当我们计算第二个偶数的时候,若依然按照以上公式,则会造成第二个偶数再次跟第一个偶数相乘,从而多出了一个答案,因此,我们算完总价值之后需要减去重复的价值,而重复的答案价值实际上就是 的种类数为 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;
}