牛客小白月赛56 A-F
牛客小白月赛56 A-F
https://ac.nowcoder.com/acm/contest/39100
一场简单的比赛就足以验证我是多么的弱智。。。
A- 阿宁的柠檬
求最大最小,签到。
注意会爆 \(int\)
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main () {
int a, b, n;
cin >> a >> b >> n;
cout << n << ' ' << (a+b)*n;
}
B - 阿宁与猫咪
构造题,一看乘,那么最小就是全1
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main () {
int m;
cin >> m;
cout << m << endl;
while (m--) cout << "1 ";
}
C - 阿宁吃粽子
还是构造
大的乘大的来构造是最优策略
先给 \(a\) 排个序,然后按照 \(0,1,2,...9\) 的顺序枚举其倍数, 依次往后填
思路是差不多了,但是码力太太太太太弱了。。。写半天都不对
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5;
int n, a[N], ans[N];
signed main () {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort (a + 1, a + n + 1);
int k = 0;
for (int i = 0; i <= 9; i++) {
for (int j = i; j <= n; j += 10) {
if (!j) continue;
ans[j] = a[++k];
}
}
for (int i = 1; i <= n; i++) cout << ans[i] << ' ';
}
//按照0,1,2,...9的顺序枚举其倍数,依次往后填
D - 阿宁的质数
预处理素数表,素数最多只有 \(2e5\) 个,然后直接查。
没做出来是因为线性筛筛错了。。
#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
const int N = 2e5 + 5;
int n, a[N], q;
bool p[N*20]; //false表素数
int main () {
ios::sync_with_stdio (0);cin.tie(0);cout.tie(0);
cin >> n >> q;
p[1] = true;
for (int i = 2; i < N*20; ++i) {
if (!p[i]) {
for (int j = i + i; j < N*20; j += i) {
p[j] = true;
}
}
}
set <int> s;
int k = 1;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
if (x < N*20 && !p[x]) s.insert (x);
while (s.count (k) || p[k]) k ++;
a[i] = k;
}
while (q --) {
int x;
cin >> x;
cout << a[x] << endl;
}
}
//只筛2e5个质数
E - 阿宁睡大觉
答案就是"EE"的个数*4,然后消除的规则是优先消去较短的夹在两个"Z"之间的"z"串
因此可以记录满足中间的所有连续"z"串的长度,用堆来挨个消。
依旧是码力太弱,虽然写出来了,但是从知道思路到实现卡了好一阵子。
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
int n, m;
string s;
int main () {
priority_queue <int, vector<int>, greater<int>> q;
cin >> n >> m >> s;
int ans = 0;
//base
int l = 0, r = 0, j = 0;
for (int i = 0; i < n; i++) {
if (s[i] == 'Z') {
if (i && j) q.push (i-j); //l=j, r=i-1;
for (j = i + 1; j < n; j++) {
if (s[j] == 'z') {
break;
}
ans += 4;
}
i = j;
}
}
while (!q.empty ()) {
int t = q.top();
q.pop();
m -= t;
if (m >= 0) ans += 4;
if (m <= 0) break;
}
cout << ans << endl;
}
//ans=4*ZZ
//把ZZ中夹着的zz删掉
F - 阿宁去游玩
由于转置不花费代价且不限次数,所以随便转,每次建最小边即可
记得开long long
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> pii;
const int N = 2e5 + 5, M = N*2;
int n, m, x, y, z;
int s[N], dis[N];
int h[N], e[M], ne[M], w[M], idx;
bool vis[N];
void add (int a, int b, int c) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}
int dijkstra () {
priority_queue <pii, vector<pii>, greater<pii>> q;
memset (dis, 0x3f, sizeof dis);
dis[1] = 0;
q.push ({0, 1});
while (!q.empty ()) {
auto t = q.top ();
q.pop ();
int ver = t.second, dist = t.first;
if (vis[ver]) continue;
vis[ver] = true;
for (int i = h[ver]; ~i; i = ne[i]) {
int j = e[i];
if (dis[j] > dist + w[i]) {
dis[j] = dist + w[i];
q.push ({dis[j], j});
}
}
}
return dis[n];
}
signed main () {
memset (h, -1, sizeof h);
cin >> n >> m >> x >> y >> z;
for (int i = 1; i <= n; i ++) cin >> s[i];
while (m --) {
int a, b, c;
cin >> a >> b;
if (s[a] == s[b]) c = min (x, y + z);
else c = min (y, x + z);
add (a, b, c), add (b, a, c);
}
cout << dijkstra () << endl;
}
//由于转置不花费代价且不限次数,所以随便转,每次建最小边即可