郑州轻工业大学2020级新生程序设计大赛题解

2024-03-27 02:20

本文主要是介绍郑州轻工业大学2020级新生程序设计大赛题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


更新了 7- 2 的代码,之前有点小 bug
更新了 7 -10 的代码,/(ㄒoㄒ)/~~
这一次真的更新好了,可以放心观看
感谢强哥等等一系列大佬给我魔法药水这个题的思路

我好菜 /(ㄒoㄒ)/


题目地址:传送门~~~


非官方题解

  • 7-1 小A与泉水
  • 7-2 小A的魔法
  • 7-3 小A的宝藏
  • 7-4 靶场射击2.0
  • 7-5 这是一个数学题
  • 7-6 代码格式化
  • 7-7 贪心的小H
  • 7-8 #define int long long
  • 7-9 小A的魔力
  • 7-10 魔法药水 (好题)

7-1 小A与泉水

思路
位运算。在二进制下,从低位开始向上进位即可。
应该还有其他写法,没再去想了 (lll¬ω¬)
这个题好像卡输入和输出,别用 cin 和 cout

AC代码

#include <iostream>
#include <bits/stdc++.h>using namespace std;int main(int argc, char** argv) {int ncase;scanf("%d", &ncase);while(ncase--){int n;scanf("%d", &n);int res = 0;if(n == 0){printf("0\n");continue;}while(n){	// 在纸上模拟一下就OK了if(n & 1){res++;if(n != 1) n += 2; }n >>= 1;}printf("%d\n", res-1);}return 0;
}

7-2 小A的魔法

思路
二维前缀和,容斥原理
~~~

黄色部分的权值 = {(7,9)->(1,1)} - {(2,9)->(1,1)} - {{(7,2)->(1,1)}} + {{(2,2)->(1,1)}}
ps: {(7,9)->(1,1)} 表示以这两个点为顶点的矩形的权值
统计权值,计算前缀和,再通过上边公式枚举所有点就OK

这里还有一种思路:
题目给的点数比较少,选取一个敌人所在的点作为矩形的一个顶点,由这个顶点确定四个矩形,再依次找在矩形内的点数有几个。
如果暴力找点的话,时间复杂度为O(n*n),妥妥的能过 手动狗头

AC代码

// 第一种思路的代码,第二种思路的代码自己试试吧
#include <iostream>
#include <bits/stdc++.h>using namespace std;const int maxn = 1e3;int v[maxn][maxn] = {0};int main(int argc, char** argv) {int n, w, k;cin >> n >> w >> k;int x, y;for(int i = 1; i <= n; i++){cin >> x >> y;v[x][y]++;}for(int i = 1; i < maxn; i++){	// 前缀和for(int j = 1; j < maxn; j++){v[i][j] += v[i][j-1] + v[i-1][j] - v[i-1][j-1];}} int res = 0; for(int i = 1; i < maxn; i++){	// 找最值for(int j = 1; j < maxn; j++){int xx = i - w + 1;int yy = j - k + 1;if(xx <= 0 || yy <= 0) continue;int tmp = v[i][j] - v[xx-1][j] - v[i][yy-1] + v[xx-1][yy-1];res = max(res, tmp);}}cout << res << endl;return 0;
}

7-3 小A的宝藏

思路
博弈论。

巴什博弈
每次有至多取走 m 个硬币,至少取走 1 个硬币。
共有 (m+1) * k + x 个硬币 (x 小于 m)。
A先手,B后手,取走最后一个硬币者胜。
分析: 如果 A 先手取走 x 个硬币,还剩下 (m+1) * k 个硬币。接下来 B 取走 z 个硬币,这时 A 可以通过取走 m+1-z 个硬币保证剩下的硬币为 m+1 的倍数。如此 K 轮以后,我们会发现 A 取走了最后一个硬币。即 A 必胜。
but,当 x 为 0 时,A 必败,类比刚刚的分析(B 在面对 (m+1) * k 时,必败)。

看完这个我们就可以知道,本题内的 m 为 3,硬币的数量就是银子的数量。
当没有金子的时候,可以知道对面 3 * k 个银子的人必输
下边我们就来分析各个情况:

3 * k 个银子,0 个金子,先手败。
3 * k + 1 个银子,0 个金子,先手胜。先手拿走一个银子,后手面对 3 * k 个银子,必败。
3 * k + 2 个银子,0 个金子,先手胜。先手拿走两个银子,后手面对 3 * k 个银子,必败。
3 * k 个银子,1 个金子,先手胜。      先手拿走一个金子,后手面对 3 * k 个银子,必败。
3 * k + 1 个银子,1 个金子,先手败。无论先手拿走什么,后手都是必胜态。
3 * k + 2 个银子,1 个金子,先手胜。先手拿走一个银子,后手面对必败态。

最后,m 个 金子可以压缩成对应的 0 或 1。
这个题同样卡输入和输出
AC代码

#include <iostream>
#include <bits/stdc++.h>using namespace std;int main(int argc, char** argv) {int ncase;scanf("%d", &ncase);while(ncase--){long long a, b;scanf("%lld %lld", &a, &b);if(a % 3 == 2) printf("Alice\n");else if(a % 3 == 0){if(b & 1) printf("Alice\n");else printf("Bob\n");}else{if(b & 1) printf("Bob\n");else printf("Alice\n");}}return 0;
}

7-4 靶场射击2.0

思路:
字符串处理,统计每个字母出现的次数找最值即可。

AC代码

#include <iostream>
#include <bits/stdc++.h>using namespace std;int v[2][26] = {0};int main(int argc, char** argv) {int n, a, b;cin >> n >> a >> b;int res = 0; char c;for(int i = 1; i <= n; i++){cin >> c;if(c >= 'a' && c <= 'z'){	// 普通 int tmp = c - 'a';v[0][tmp]++;res = max(res, v[0][tmp] * b + v[1][tmp] * a);}else{		// 特殊 int tmp = c - 'A';v[1][tmp]++;res = max(res, v[0][tmp] * b + v[1][tmp] * a);}}for(int i = 0; i < 26; i++){if(v[0][i] * b + v[1][i] * a == res){cout << (char)(i + 'A') << endl;break;}}return 0;
}

7-5 这是一个数学题

思路
思维题~~~
如果一个数是 20 的倍数那么最后两位数要为偶数和一个零。
把一个数往这个状态转移,看需要换几次即可。
如果达不到这个状态,结果就为 -1。

AC代码

#include <iostream>
#include <bits/stdc++.h>using namespace std;int main(int argc, char** argv) {int ncase;cin >> ncase;while(ncase--){long long n;cin >> n;if(n < 20){cout << -1 << endl;continue;}vector<int> v;while(n){int tmp = n % 10;v.push_back(tmp);n /= 10;}int res = 0;if(v[0] != 0){int f = 0;for(int i = 2; i < v.size(); i++){if(v[i] == 0){swap(v[0], v[i]);f = 1;res++;break;}}if(f == 0 && v[1] == 0){swap(v[0], v[1]);res++;}else if(f == 0) res = -1;}if(v[1] % 2 != 0 && res != -1){int f = 0;for(int i = 2; i < v.size(); i++){if(v[i] % 2 == 0){swap(v[1], v[i]);f = 1;res++;break;}}if(f == 0) res = -1;}cout << res << endl;}return 0;
}

7-6 代码格式化

思路
字符串处理。

AC代码

#include <bits/stdc++.h>
using namespace std;string s, ss;int main(){getline(cin, ss);getline(cin, s);cout << ss << endl;int len = s.size();for(int i = 0; i < len; i++){if(s[i] == '{') cout << " " << s[i] << endl << "    ";else if(s[i] == ';' && i+2 != len) cout << s[i] << endl << "    ";else if(s[i] == ';') cout << s[i] << endl;else if(s[i] == '=') cout << " " << s[i] << " ";else if(s[i] == '+') cout << " " << s[i] << " ";else if(s[i] == '-') cout << " " << s[i] << " ";else if(s[i] == '*') cout << " " << s[i] << " ";else if(s[i] == '/') cout << " " << s[i] << " ";else if(s[i] == '%') cout << " " << s[i] << " ";else cout << s[i];}cout << endl;return 0;
}

7-7 贪心的小H

思路
假设当前背包有 x 个物品,价值为 y,对于未放入背包价位为 val 物品 A:
如果我们把它放入背包,背包的价值变为 (x+1) * (y + val), 展开得 x*y + y + (x+1) * val。
贪心得,如果 y + (x+1) * val 大于零,我们就把它放入背包。
对所有物品,按照 val 排序,从大到小去判断即可。

AC代码

#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#define ll long long
#define chushi(a, b) memset(a, b, sizeof(a))
#define endl "\n"
const double eps = 1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
const int maxn = 1e5 + 5;using namespace std;typedef struct Node{int id;int val;
} node;bool cmp(node A, node B){if(A.val == B.val) return A.id < B.id;return A.val > B.val;
}node a[205];int main(){int n;cin >> n;for(int i = 1; i <= n; i++) cin >> a[i].id;for(int i = 1; i <= n; i++) cin >> a[i].val;sort(a+1, a+1+n, cmp);int x = 0, y = 0;for(int i = 1; i <= n; i++){if(a[i].id == a[i-1].id) continue;if(y + (x+1) * a[i].val > 0){x += 1;y += a[i].val;}else break;}cout << x * y << endl;return 0;
}

7-8 #define int long long

签到题。

AC代码

#include <bits/stdc++.h>
using namespace std;int main(){for(int i = 1; i <= 10; i++) cout << "#define int long long" << endl;return 0;
}

7-9 小A的魔力

思路
按照题意取最大值对应的字符串即可。

AC代码

#include <bits/stdc++.h>
using namespace std;int main(){int n;cin >> n;int mx = -1, tmp; string res, s;for(int i = 1; i <= n; i++){cin >> s >> tmp;if(tmp > mx){mx = tmp;res = s;}}cout << res << endl;return 0;
}

7-10 魔法药水 (好题)

思路
二分答案,在贪心wa了一以后就感觉是二分答案,不过一直想不到check函数咋写。

答案要的是价值和大于等于 X 的最少药瓶数,优先取价值大的药水这样想肯定没问题。

本人第一想法:
依次取价值最大和次大的药水轮流放,然后被自己无情 hack
这里给出一组 hack 数据:
     4   67
     4   10
     3    5
     10   4
     10   1
答案是:10
其中一个满足的排列:10、4、5、10、4、5、10、4、5、10

下边来说说正解:
二分答案。每次取验证一个瓶子数是不是能满足题意,在所有满足题意里边取最优。
这里说一个点,对于第 i 种药水,它在一个需要 X 个药水的方案种能使用的最多药水数为:(X+1)/ 2
看图吧,应该看得懂对于 X 的奇偶性质,自己画个图数数就知道了
抽象派画手
其他的细节看代码,详解,保懂。

AC代码

#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#define ll long long
#define chushi(a, b) memset(a, b, sizeof(a))
#define endl "\n"
const double eps = 1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
const int maxn = 1e5 + 5;using namespace std;typedef struct Node{ll num;ll val;
} node;bool cmp(node A, node B){	// 自定义排序,主要是按照价值排序,数量无所谓 if(A.val == B.val) return A.num > B.num;return A.val > B.val;
}ll n, x;
node a[maxn];int check(ll mid){	// check 函数 ll cnt = mid, sum = x;	// 有 mid 个 位置放药水,需要达到价值 sum for(int i = 1; i <= n; i++){				// 遍历,提前排过序的 ll num = a[i].num, w = a[i].val;		// 第 i 种药水的数量 和 单个的价值 ll tmp = min({num, (mid+1)/2, cnt});	// 对于当前情况,这个药水能用的最多个数是://	当前药水的数量、一个方案里一种药水最多可以放多少个位置、还需要的药水数。三者取 min。 sum -= tmp * w;	// 减去这个药水贡献的价值 cnt -= tmp;		// 减去这个药水贡献的数量 if(cnt == 0) break;	// 数量满足就提前结束 }if(cnt > 0) return 1;	// 药水不够填满 mid 个位置 if(sum <= 0) return 2;	// 药水可以填满 mid 个位置,并且满足价值大于 x return 0;				// 不满足价值大于 x 
}int main(){cin >> n >> x;for(int i = 1; i <= n; i++) cin >> a[i].num >> a[i].val;sort(a+1, a+1+n, cmp);		// 按权值排序,贪心思想,优先取权值大的 ll l = 1, r = 1e18, res = -1;	// 二分答案 while(l <= r){ll mid = l + r >> 1;int op = check(mid);if(op == 1) r = mid -1;else if(op == 2) r = mid - 1, res = mid;else l = mid + 1;}cout << res << endl;return 0;
}

写在最后,这次最后这个题是我的锅,以后再也不提前写题解了,脸疼(;´д`)ゞ
下 次 还 会


这篇关于郑州轻工业大学2020级新生程序设计大赛题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/850648

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

C语言程序设计(数据类型、运算符与表达式)

一、C的数据类型 C语言提供的数据类型: 二、常量和变量 2.1常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。 常量区分为不同的类型: 程序中用#define(预处理器指令)命令行定义变量将代表常量,用一个标识符代表一个常量,称为符合常量。 2.2变量 变量代表内存中具有特定属性的一个存储单元,用来存放数据,在程序运行期间,这些值是可以 改变的。 变

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

C语言程序设计(选择结构程序设计)

一、关系运算符和关系表达式 1.1关系运算符及其优先次序 ①<(小于) ②<=(小于或等于) ③>(大于) ④>=(大于或等于 ) ⑤==(等于) ⑥!=(不等于) 说明: 前4个优先级相同,后2个优先级相同,关系运算符的优先级低于算术运算符,关系运算符的优先级高于赋值运算符 1.2关系表达式 用关系运算符将两个表达式(可以是算术表达式或关系表达式,逻辑表达式,赋值表达式,字符

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析

牛客小白月赛100部分题解

比赛地址:牛客小白月赛100_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ A.ACM中的A题 #include<bits/stdc++.h>using namespace std;#define ll long long#define ull = unsigned long longvoid solve() {ll a,b,c;cin>>a>>b>