西南民族大学 春季 2023 训练赛 5
L1-1 自动编程
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main() {
int n;
cin >> n;
printf("print(%d)\n" , n );
return 0;
}
L1-2 太神奇了
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main() {
int a , b;
cin >> a >> b;
cout << a + b - 1 << "\n";
return 0;
}
L1-3 洛希极限
#include <bits/stdc++.h>
using namespace std;
int32_t main() {
double a, c;
int b;
cin >> a >> b >> c;
if (b == 0) a = a * 2.455;
else a = a * 1.26;
printf("%.2lf ", a);
if (c - a > 1e-3) cout << "^_^\n";
else cout << "T_T\n";
return 0;
}
L1-4 吃鱼还是吃肉
#include <bits/stdc++.h>
using namespace std;
int32_t main() {
int n;
cin >> n;
while( n -- )
{
int a, b, c;
cin >> a >> b >> c;
if (a == 1) {
if (b > 130) cout << "ni li hai! ";
else if (b < 130) cout << "duo chi yu! ";
else cout << "wan mei! ";
if (c > 27) cout << "shao chi rou!\n";
else if (c < 27) cout << "duo chi rou!\n";
else cout << "wan mei!\n";
} else {
if (b > 129) cout << "ni li hai! ";
else if (b < 129) cout << "duo chi yu! ";
else cout << "wan mei! ";
if (c > 25) cout << "shao chi rou!\n";
else if (c < 25) cout << "duo chi rou!\n";
else cout << "wan mei!\n";
}
}
return 0;
}
L1-5 不变初心数
#include <bits/stdc++.h>
using namespace std;
int32_t main() {
int n;
cin >> n;
while (n--) {
int x, y = 0, z, f = 1;
cin >> x;
z = x * 2;
while (z) y += z % 10, z /= 10;
for (int i = 3, t; f && i <= 9; i++) {
z = x * i, t = 0;
while (z) t += z % 10, z /= 10;
if (t != y) f = 0;
}
if (f) cout << y << "\n";
else cout << "NO\n";
}
return 0;
}
L1-6 字母串
#include <bits/stdc++.h>
using namespace std;
int32_t main() {
int n;
cin >> n;
while( n -- ){
string s;
cin >> s;
bool f = true;
for( int i = 0; f && i < s.size()-1 ; i ++ ){
if( s[i] >= 'A' && s[i] <= 'Z' ){
if( s[i+1] != s[i] + 'a' - 'A' && s[i+1] != s[i]+1 ) f = false;
}else{
if( s[i+1] != s[i] + 'A' - 'a' && s[i+1] != s[i]-1 ) f = false;
}
}
if( f ) cout << "Y\n";
else cout << "N\n";
}
return 0;
}
L1-7 矩阵列平移
题目的意思是\(1,2,\dots,k,1,2,\dots k,\dots\)不是\(1,k,1,k,1,k,\dots\)
#include <bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
int n = read(), k = read(), t = read();
vector<vector<int>> a(n + 1, vector<int>(n + 1));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
a[i][j] = read();
for (int j = 2, p = 1; j <= n; j += 2) {
for (int i = n; i > p; i--)
a[i][j] = a[i - p][j];
for (int i = 1; i <= p; i++)
a[i][j] = t;
p++;
if (p == k + 1) p = 1;
}
for (int i = 1, sum; i <= n; i++) {
sum = 0;
for (int j = 1; j <= n; j++) sum += a[i][j];
cout << sum << " \n"[i == n];
}
return 0;
}
L1-8 均是素数
先跑个筛法,然后枚举一下素数,最后暴力判断一下素数就好了。
#include <bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
bool isPrime(int x) {
for (int i = 2; i * i <= x; i++) {
if (x % i) continue;
return false;
}
return true;
}
int32_t main() {
int l = read(), r = read();
vector<bool> notPrime(r + 1);
vector<int> pr;
notPrime[0] = notPrime[1] = 1;
for (int i = 2; i <= r; i++) {
if (notPrime[i]) continue;
for (int j = i * 2; j <= r; j += i)
notPrime[j] = 1;
}
for (int i = l; i <= r; i++) {
if (notPrime[i]) continue;
pr.push_back(i);
}
int cnt = 0;
for (int p = 0; p < pr.size(); p++)
for (int q = p + 1; q < pr.size(); q++)
for (int r = q + 1; r < pr.size(); r++) {
if (isPrime(pr[p] * pr[q] + pr[r]) && isPrime(pr[q] * pr[r] + pr[p]) && isPrime(pr[r] * pr[p] + pr[q]))
cnt++;
}
cout << cnt << "\n";
return 0;
}
L2-1 盲盒包装流水线
就是搞个小模拟
#include <bits/stdc++.h>
using namespace std;
int32_t main() {
ios::sync_with_stdio(false),cin.tie(nullptr) , cout.tie(nullptr);
int n , s;
cin >> n >> s;
vector<string> box(n);
for( auto &i : box ) cin >> i;
map<string,int> cnt;
vector<int> stk(s);
for( int t = n/s , i = 0; t ; t -- ){
for( auto &j : stk ) cin >> j;
reverse(stk.begin() , stk.end() );
for( auto j : stk )
cnt[ box[i++] ] = j;
}
int k;
cin >> k;
while( k -- ){
string id;
cin >> id;
if( cnt.find(id) == cnt.end() ) cout << "Wrong Number\n";
else cout << cnt[id] << "\n";
}
return 0;
}
L2-2 点赞狂魔
结构体排序
#include <bits/stdc++.h>
using namespace std;
struct Node {
string name;
int n;
set<int> cnt;
Node() {}
bool operator<(Node b) const {
if (cnt.size() != b.cnt.size()) return cnt.size() > b.cnt.size();
return n < b.n;
}
};
int32_t main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int n;
cin >> n;
vector<Node> a(n);
for (auto &i: a) {
cin >> i.name >> i.n;
for (int j = 1, x; j <= i.n; j++)
cin >> x, i.cnt.insert(x);
}
sort(a.begin(), a.end());
for (int i = 0; i < min(3, n); i++)
cout << a[i].name << " \n"[i == 2];
for (int i = max(0, 3 - n); i; i--)
cout << "-" << " \n"[i == 1];
return 0;
}
L2-3 浪漫侧影
把二叉树建好,然后跑一下层序遍历
#include <bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
struct Node {
int v;
Node *l, *r;
Node(int v, Node *l, Node *r) : v(v), l(l), r(r) {};
};
Node *build(vector<int> mid, vector<int> suf) {
int v = suf.back();
Node *l = nullptr, *r = nullptr;
int t;
for (t = 0; t < mid.size(); t++)
if (mid[t] == v) break;
auto midll = mid.begin();
auto midlr = mid.begin() + t;
auto midrl = mid.begin() + t + 1;
auto midrr = mid.end();
auto sufll = suf.begin();
auto suflr = suf.begin() + t;
auto sufrl = suf.begin() + t;
auto sufrr = suf.end() - 1;
auto midl = vector<int>(midll, midlr);
auto midr = vector<int>(midrl, midrr);
auto sufl = vector<int>(sufll, suflr);
auto sufr = vector<int>(sufrl, sufrr);
if (!midl.empty()) l = build(midl, sufl);
if (!midr.empty()) r = build(midr, sufr);
return new Node(v, l, r);
}
int32_t main() {
int n = read();
vector<int> mid(n), suf(n);
for (auto &i: mid) i = read();
for (auto &i: suf) i = read();
auto v = vector<int>(mid.begin(), mid.begin() + 3);
Node *root = build(mid, suf);
vector<int> L, R;
map<int, int> dep;
queue<pair<Node *, int>> q;
dep[root->v] = 1, q.emplace(root, 1);
while (!q.empty()) {
auto [u, d] = q.front();
q.pop();
if (L.empty()) L.push_back(u->v);
else if (d != dep[L.back()]) L.push_back(u->v);
if (R.empty()) R.push_back(u->v);
else if (d != dep[R.back()]) R.push_back(u->v);
else R.back() = u->v;
if (u->l != nullptr) {
dep[u->l->v] = d + 1;
q.emplace(u->l, d + 1);
}
if (u->r != nullptr) {
dep[u->r->v] = d + 1;
q.emplace(u->r, d + 1);
}
}
cout << "R:";
for (auto i: R) cout << " " << i;
cout << "\nL:";
for (auto i: L) cout << " " << i;
return 0;
}
L2-4 哲哲打游戏
把图建出来然后模拟这个过程就好了
#include <bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
int n = read() , m = read();
vector<vector<int>> e(n+1);
for( int i = 1 , k ; i <= n ; i ++ ){
k = read();
e[i] = vector<int>(k+1);
for( int j = 1 ; j <= k ; j ++ ) e[i][j] = read();
}
vector<int> s(101,-1);
int t = 1;
for( int op , x ; m ; m -- ){
op = read() , x = read();
if( op == 0 ) t = e[t][x];
else if( op == 1 )
s[x] = t , printf("%d\n" , t);
else t = s[x];
}
printf("%d\n" , t );
return 0;
}
L3-1 直捣黄龙
首先从终点跑一遍 dij,然后从七点开始跑一遍暴搜就可。
#include <bits/stdc++.h>
using namespace std;
const int N = 205;
int n, k, s, e;
string sta, ed;
int val[N], dis[N], vis[N];
vector<pair<int, int>> g[N];
unordered_map<string, int> sti;
unordered_map<int, string> its;
vector<int> ans, now;
int ansdis = -1, anscnt = -1 , anstimes;
void dij() {
fill(dis + 1, dis + 1 + n, INT_MAX);
dis[e] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
q.emplace(0, e);
while (!q.empty()) {
auto [d, u] = q.top();
q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (auto [v, w]: g[u]) {
if (vis[v]) continue;
if (dis[v] <= d + w) continue;
dis[v] = d + w, q.emplace(dis[v], v);
}
}
return;
}
void dfs(int x, int d, int cnt) {
if (d + dis[x] > ansdis) return;
if (x == e && d == ansdis ) {
anstimes ++;
if (now.size() > ans.size()) {
anscnt = cnt, ans = now;
} else if (now.size() == ans.size() && cnt > anscnt) {
anscnt = cnt, ans = now;
}
return;
}
for (auto [v, w]: g[x]) {
if (vis[v]) continue;
now.push_back(v), vis[v] = 1;
dfs(v, d + w, cnt + val[v]);
now.pop_back(), vis[v] = 0;
}
return;
}
int32_t main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
cin >> n >> k >> sta >> ed;
sti[sta] = 1, its[1] = sta;
for (int i = 2; i <= n; i++)
cin >> its[i] >> val[i], sti[its[i]] = i;
s = sti[sta], e = sti[ed];
for (int u, v, w; k; k--) {
string us, vs;
cin >> us >> vs >> w;
u = sti[us], v = sti[vs];
g[u].emplace_back(v, w);
g[v].emplace_back(u, w);
}
dij();
fill(vis, vis + 1 + n, 0);
ansdis = dis[s], vis[s] = 1;
dfs(s, 0, 0);
cout << sta;
for (auto i : ans)
cout << "->" << its[i];
cout << "\n" << anstimes << " " << ansdis << " " << anscnt << "\n";
return 0;
}
L3-2 拼题A打卡奖励
正常的想法是就是01背包,\(f[i]\)表示用时\(i\)能否获得最多的金币,但是\(i\)的取值太大了,这里可以改成表示为获得金币\(i\)的最少用时,倒序遍历第一个小于\(f[i]<m\)的\(i\)就是答案
#include <bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
int n = read(), m = read(), k = 0;
vector<int> w(n), v(n);
for (int &i: w) i = read();
for (int &i: v) i = read(), k += i;
vector<int> f(k + 1, INT_MAX);
f[0] = 0;
for (int i = 0; i < n; i++) {
for (int j = k; j >= v[i]; j--) {
if (f[j - v[i]] == INT_MAX) continue;
f[j] = min(f[j], f[j - v[i]] + w[i]);
}
}
for (int i = k; i >= 0; i--)
if (f[i] <= m) cout << i, exit(0);
return 0;
}