2025年河南工业大学2025新生周赛(4)
A 编程大蛇dream
直接输出即可,注意‘\’、‘"’等需要特殊处理的符号,同时注意空格数量需要对应。
void solve(){
printf("#《incldue std1o。h)\n1nt man()[\n print(“holIe word\\n\";)\n retrun o:\n}");
}
额外介绍一种c++的输出方法
void solve(){
cout<<R"(请输入文本)";
}
B 梦应归于何处
在传送站i,只要a_i>=a_(i+1)-b_(i+1)即可传送到i+1
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int n;scanf("%d", &n);
int a[10007] = { 0 }, b[10007] = { 0 };
for (int i = 0;i < n;i++) {
scanf("%d", &a[i]);
}
for (int i = 0;i < n;i++) {
scanf("%d", &b[i]);
}
int ans = 0;
int cur = 0;
for (int i = 0;i < n;i++) {
if (a[i] - b[i] <= cur) {
ans = i + 1;
cur = a[i];
}
else break;
}
printf("%d\n", ans);
return 0;
}
C 卡厄斯兰娜的33550336次轮回
范围内的完美数有6,28,8128,33550336,8589869056.
可以直接找一下cur=2^i-1为质数,并计算此时的完美数即可
解释:第0世的卡厄斯兰娜在第6世的结尾将使命交给第6世界,因此第6世初是第0世的,第7世初是第6世的。
0-6世为第0世的卡厄斯兰娜,7-8128世为第6世的,以此类推。
//注意<<在处理longlong时容易出问题,最好自定义pow
#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;
#define int long long
int pow(int a, int b) {
int ans = 1;
while (b--) {
ans *= a;
}
return ans;
}
signed main()
{
int save[10];
int cnt = 0;
int perfect[1000];
perfect[0] = 0;
for (int i = 2;i <= 20;i++) {//获取完美数,单独写一个程序获取然后全部if-else判断输出也可以
int cur = (1 << i) - 1;
int flag = 1;
for (int j = 2;j <= sqrt(cur);j++) {
if (cur % j == 0) {
flag = 0;break;
}
}
if (flag) {
perfect[++cnt] = pow(2, i - 1) * (pow(2, i) - 1);
// printf("%lld\n", perfect[cnt]);
}
}
perfect[++cnt] = 1e17;
int n;scanf("%lld", &n);
if (n == 0) {
std::cout << 0;
return 0;
}
// cout << n << endl;
for (int i = 0;i <= cnt;i++) {
if (n > perfect[i] && n <= perfect[i + 1]) {
printf("%lld", perfect[i]);
}
}
}
D AK路上的绊脚山
二分答案,O(n) 进行check即可秒出,无需快排等O(nlogn)的排序方法.
#include <stdio.h>
#define int long long
int h[100007];
int n, k;
bool check(int mid) {
int sum = 0;
for (int i = 1;i <= n;i++) {
if (h[i] >= mid)sum += mid;
else sum += h[i];
}
return sum <= k;
}
signed main()
{
scanf("%lld %lld", &n, &k);
int mx = 0;
for (int i = 1;i <= n;i++) {
scanf("%lld", &h[i]);
mx = mx > h[i] ? mx : h[i];
}
int l = 0, r = mx;
while (l < r) {
int mid = l + r + 1 >> 1;
if (!check(mid))r = mid - 1;
else l = mid;
}
printf("%d\n", l);
}
E 萤火虫大战真蛰虫
直接递归或者队列/栈,也是一个模拟题
萤火虫与爆炸的真蛰虫作用一样,每次进入相同队列即可。递归代码更简,这里给出队列做法
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, k;cin >> n >> k;
int grid[102][102] = { 0 };
int boomx[10007];
int boomy[10007];
int top = -1;
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= n;j++) {
cin >> grid[i][j];
}
}
while (k--) {
int x, y;cin >> x >> y;
++top;
boomx[top] = x;
boomy[top] = y;
while (top >= 0) {
int cx = boomx[top];
int cy = boomy[top];
top--;
for (int i = cx - 1;i <= cx + 1;i++) {
for (int j = cy - 1; j <= cy + 1;j++) {
if (grid[i][j] > 1)grid[i][j]--;
else if (grid[i][j] == 1) {
top++;
grid[i][j]--;
boomx[top] = i;
boomy[top] = j;
}
}
}
}
}
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= n;j++) {
if (grid[i][j]) {
cout << "NO" << endl;
return 0;
}
}
}
cout << "YES" << endl;
return 0;
}
F 幽蝶能留一缕芳
贪心,n^2排序后枚举有相邻的数量并判断可行性,然后更新ans
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
signed main()
{
int t;t = 1;
while (t--) {
int n, m;cin >> n >> m;
vector<pair<int, pair<int, int>>>save;//a-b,a,b
for (int i = 0;i < n;i++) {
int a, b;cin >> a >> b;//存在,不存在
save.push_back({ a - b,{a,b} });
}
sort(save.begin(), save.end(), greater<pair<int, pair<int, int>>>());//降序排序,
int ans = 0;int cnt = 0;
for (int i = 0;i < save.size();i++) { cnt += save[i].se.se; }
//cnt计算全有相邻
if (0 + 2 * (n - 0) - 1 <= m) {//全部没有相邻
ans = max(ans, cnt);
}
cnt += save[0].fi;
for (int k = 2;k <= n;k++) {//2-n遍历有相邻的数量
cnt += save[k - 1].fi;
if (k + 2 * (n - k) <= m) {//注意留的空白点位数量
ans = max(ans, cnt);
}
}
cout << ans << endl;
}
}
G 冥界的人员统计
依然模拟,没什么好讲的
C++用map或者C用暴力都能过
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;cin >> n;
map<string, int>mp;
while (n--)
{
string s;cin >> s;
if (!mp.count(s))
{
mp[s] = 1;
cout << "OK\n";
continue;
}
string ss = s;
s = s + to_string(mp[s]);
cout << s << endl;
mp[ss]++;
}
return 0;
}
H Crychic的解散
本质是计算2和5的数量,2*5可获取一个0
8=2^3 4=2^2 2=2^1
8计为3个2,4计为2个2,6计一个
答案就是min(cnt2,cnt5)
#include <stdio.h>
#include <string.h>
int main()
{
char s[100007];
scanf("%s", s);
int len = strlen(s);
int cnt2 = 0, cnt5 = 0;
int i = (s[0] == '-' ? 1 : 0);
for (;i < len;i++) {
int cur = s[i] - '0';
if (cur == 0) {
printf("1\n");
return 0;
}
if (cur % 2 == 0) {
if (cur == 2 || cur == 6)cnt2++;
if (cur == 4)cnt2 += 2;
if (cur == 8)cnt2 += 3;
}
if (cur % 5 == 0)cnt5 += cur / 5;
}
int ans = cnt2 > cnt5 ? cnt5 : cnt2;
printf("%d", ans);
}
ps:H由于样例不强,有些别的错解也能ac,可以自行检查一遍
ps:H由于样例不强,有些别的错解也能ac,可以自行检查一遍


浙公网安备 33010602011771号