JXUST_NC - ACM工作室20级选拔赛题解
A - RioTian学长的星际航线
并查集板子
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int n, m; //星球数和星际航线数M。
int a, b, father[maxn];
int find(int x) {
int r = x;
while (r != father[r]) r = father[r];
int i = x, j;
while (father[i] != r) {
j = father[i];
father[i] = r;
i = j;
}
return r;
}
int main() {
while (cin >> n && n) {
cin >> m;
//初始化。
for (int i = 1; i <= n; i++) father[i] = i;
while (m--) {
cin >> a >> b;
a = find(a), b = find(b);
if (a != b) father[a] = b;
}
int cnt = 0;
for (int i = 1; i <= n; i++) {
if (father[i] == i) cnt++;
}
cout << cnt - 1 << endl;
}
return 0;
}
B - 江理大家庭
根据题意不断模拟。
#include <bits/stdc++.h>
using namespace std;
string s;
bool judge1(char a) {
if (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u') return true;
else
return false;
}
bool judge2(string s) {
bool flag1 = false, flag2 = true, flag3 = true;
//若为1说明前者为元音,若为-1说明还没有确定,若为0说明前者为辅音。
int flag = -1;
int len = s.size();
int cnt = 1; //统计连续的原因。
char pre = '0';
for (int i = 0; i < len; i++) {
if (judge1(s[i])) flag1 = true;
if (pre != '0') {
//连续字母的判断。
if (pre == s[i]) {
if (pre != 'e' && pre != 'o') flag3 = false;
} else
pre = s[i];
}
if (flag != -1) {
if (flag) {
//说明为元音,那么判断后者是否为元音。
if (judge1(s[i])) cnt++;
else {
//为辅音就改变。
cnt = 1;
flag = 0;
}
} else {
if (!judge1(s[i])) cnt++;
else {
cnt = 1;
flag = 1;
}
}
if (cnt == 3) flag2 = false;
}
if (pre == '0') pre = s[i];
if (flag == -1) {
if (judge1(s[i])) flag = 1;
else
flag = 0;
}
}
if (flag1 && flag2 && flag3) return true;
else
return false;
}
int main() {
while (cin >> s) {
if (s == "end") break;
cout << "<" << s << "> ";
cout << (judge2(s) ? "is acceptable.\n" : "is not acceptable.\n");
}
return 0;
}
C - 粗心的RioTian学长
数组绝对值排序
#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
int n, a[maxn];
bool cmp(int a, int b) { return abs(a) > abs(b); }
int main() {
while (cin >> n) {
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n, cmp);
for (int i = 0; i < n; i++) {
cout << a[i];
i == n - 1 ? cout << endl : cout << " ";
}
}
return 0;
}
D - 女装大佬RioTian
利用双指针寻找
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int t, n, s, min_len;
int a[maxn];
int main() {
cin >> t;
while (t--) {
cin >> n >> s;
for (int i = 0; i < n; i++) cin >> a[i];
min_len = maxn;
int sum = 0, cur = 0, last = 0; //双指针。
while (cur < n) {
sum += a[cur];
while (sum >= s) {
min_len = min(min_len, cur - last + 1);
sum -= a[last++];
}
cur++;
}
if (min_len == maxn) {
cout << "0" << endl;
} else {
cout << min_len << endl;
}
}
return 0;
}
E - RioTian学长的数组
简单贪心思想
字典序最小,首先让最前面的最小,最后面最大
void solve() {
int n, k;
cin >> n >> k;
int a[n + 1];
for (int i = 1; i <= n; ++i) cin >> a[i];
int i = 1, j = n;
while (true) {
if (i == j || k == 0) break;
if (a[i] >= 1) a[i] -= 1, a[j] += 1, k--;
else
i++;
}
for (int i = 1; i <= n; ++i) cout << a[i] << " ";
cout << "\n";
}
F - RioTian学长爱照相
要使 (au + av) / 2 为整数的上镜对越多,那么简单来说,奇数和奇数成对,偶数与偶数组队,这样上镜对一定最大
void solve() {
int n;
cin >> n;
vector<int> a(n);
vector<int> odd, even;
for (int &x : a) {
cin >> x;
if (x & 1) odd.push_back(x);
else
even.push_back(x);
}
for (int x : odd) cout << x << " ";
for (int x : even) cout << x << " ";
cout << '\n';
}
G - RioTian学长与矩阵
概括一下题意:在一个被限定了宽度的盒子中给一些长度为
思路:先利用 map
存储各个长度的值,然后二分找到在该行中最大的一块然后填充。
void solve() {
int n, w;
cin >> n >> w;
map<int, int> mp;
for (int i = 0, x; i < n; ++i) {
cin >> x;
mp[x]++;
}
int ans = 1, cur = w;
while (mp.size()) {
if (mp.begin()->first > cur) {
++ans, cur = w;
}
auto it = prev(mp.upper_bound(cur));
assert(it->first <= cur);
cur -= it->first;
if (--(it->second) == 0) mp.erase(it);
}
cout << ans << "\n";
}
H - 字符串的最小开销
这是一道比较难的字符串思维题
总而言之就是让连续的两个ij 出现尽可能少的次数,尽可能平均,所以直接让ababc....akbcbdbe...bkc这样过去,然后最后到(k-1)k 又连到a,刚好所有连续两个出现了一次,这样还不够的话继续循环下去就行了
void solve() {
int n, k;
cin >> n >> k;
string s;
for (int i = 0; i < k; ++i) {
s += 'a' + i;
for (int j = i + 1; j < k; ++j) s += 'a' + i, s += 'a' + j;
}
assert(s.size() == k * k);
for (int i = 0; i < n; ++i) cout << s[i % s.size()];
}
I - RioTian学长爱玩消消乐
首先给数组排序,如果存在相邻差值大于2的则输出 NO
#include <bits/stdc++.h>
using namespace std;
int main() {
int t, n, a[1100];
cin >> t;
while (t--) {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n);
int flag = 0;
for (int i = 1; i < n && !f; i++) {
if (abs(a[i] - a[i - 1]) >= 2)
flag = 1;
}
if (flag)
cout << "NO" << endl;
else
cout << "YES" << endl;
}
}
J - Hello,World!
签到题
cout << "hello world";
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 分享4款.NET开源、免费、实用的商城系统
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
· 5. Nginx 负载均衡配置案例(附有详细截图说明++)
2020-04-25 #2063 过山车(二分图入门题)
2020-04-25 VS遇到 error C4996问题的解决方法
2020-04-25 #2059:龟兔赛跑(动态规划dp)