第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛题解
第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛题解
先抱怨一下,这场比赛的题锅太多了,而且正赶上状态不好,Ac 1/12就离谱。。
H 数羊
给定n,m(1≤n≤109,0≤m≤2)n,m(1\leq n \leq 10^9,0\leq m \leq 2)n,m(1≤n≤109,0≤m≤2),计算A(n,m)A(n, m)A(n,m),以下给出A(n,m)A(n,m)A(n,m)公式:
{A(1,0)=2A(0,m)=1m≥0A(n,0)=n+2n≥2A(n,m)=A(A(n−1,m),m−1)n,m≥1\begin{cases} A(1,0)=2\\ A(0,m) = 1 \quad m \geq 0\\ A(n,0)=n+2 \quad n \geq 2 \\ A(n,m) = A(A(n-1, m), m-1)\quad n,m \geq 1 \end{cases} ⎩⎪⎪⎪⎨⎪⎪⎪⎧A(1,0)=2A(0,m)=1m≥0A(n,0)=n+2n≥2A(n,m)=A(A(n−1,m),m−1)n,m≥1
做法非常多的简单题:不管是打表还是按照公式推都可做。但关键在于mmm的取值范围(一定要注意mmm的范围,不然打表轻松stackoverflow,我说怎么大家都说打表可做,我就stackoverflow了。。。)
在mmm的取值范围内,打表即可找出规律:
m=0时,A(n,0)=n+2;m=1时,A(n,1)=2⋅nm=2时,A(n,2)=2nm=0时,A(n,0)=n+2;\\ m=1时,A(n,1)=2\cdot n\\ m=2时,A(n,2)=2^nm=0时,A(n,0)=n+2;m=1时,A(n,1)=2⋅nm=2时,A(n,2)=2n
D Seek the joker I
n(n≤105)n(n\leq 10^5)n(n≤105)张扑克牌的牌堆,最下面一张是龟牌,抽到的人输。现在每人每次至多抽k(k≤105)k(k \leq 10^5)k(k≤105)张,至少抽一张。判断先/后手必胜。声明:本题中的所有角色在剧情发生时均已超过18岁。
yo xi no forever!
一个简单的巴什博弈。抽到第nnn张的人输,说明胜者抽走了第n−1n-1n−1张。
套一下巴什博弈公式即可
E Seek the joker II
n(n≤105)n(n\leq 10^5)n(n≤105)张扑克牌的牌堆,从上往下第xxx张是龟牌,抽到的人输。现在每人可以在牌堆底/顶/同时抽任意张,但至少抽一张,并且在牌堆上下同时抽必须抽走相同数目的牌。判断先/后手必胜。声明:本题中的所有角色在剧情发生时均已超过18岁。
yo xi no forever!
一道威佐夫博弈题。但我当时没学过威佐夫博弈,还当是尼姆博弈变形来做。。。
龟牌将牌堆分为两部分,一部分为x−1x-1x−1张,一部分为n−xn-xn−x张。
引入概念:
局势:用(ak,bk)(a_k,b_k)(ak,bk)表示两堆牌中剩余牌的数量。称之为局势
奇异局势:如果处于某种局势下的一方必输,则称为奇异局势。
威佐夫博弈的结论是:
- 第iii个奇异局势的差值是iii
- 每一个状态的第一个都是以前没有出现过的最小非负整数。
- ak=[k(1+√5)2],bk=ak+k(k=0,1,2,…,n)a_k =[\frac{k(1+√5)}{2} ],b_k= a_k + k (k=0,1,2,…,n )ak=[2k(1+√5)],bk=ak+k(k=0,1,2,…,n)为奇异局势的通式。
证明不会,贴个外链吧[证明]
判断:判aka_kak是否等于两数差值乘以黄金分割比向下取整即可
#include<bits/stdc++.h>
using namespace std;int n, m;
const double lorry = (sqrt(5.0) + 1.0) / 2.0;int main() {cin >> n >> m;if(n < m) swap(n, m);int a = n - m;if(m == int(lorry * (double)a))cout << "NO" << endl;else cout << "YES" << endl;
}
I 买花
给定一个数nnn,即需要买nnn多花,后一天买的花数为前一天两倍。问是否能在k(1<k≤15)k(1<k\leq 15)k(1<k≤15)天内恰好买到nnn朵花。
假设第一天买xxx朵花,考察以下等比数列:
x,2x,4x,...,2k−1xx,2x,4x,...,2^{k-1}xx,2x,4x,...,2k−1x,其和为x(2k−1)x(2^k-1)x(2k−1)。因为kkk有范围,我们可以枚举kkk,然后判断对于给定的nnn,是否存在xxx(也就是整除)。
(鬼知道我当时脑子抽了什么风没想到整除。。。)
C 上进的凡凡
给定一个长为n(1≤n≤105)n(1\leq n \leq 10^5)n(1≤n≤105)数组,判断数组的非降序子数组的个数。子数组定义为:在原数组头尾删除任意元素和得到的数组。子数组包含原数组,不包含空串。
我当时写的代码事后一看过了九成的测试用例。那么究竟是错哪了呢?
我爆int了
三年竞赛一场空,不开longlong见祖宗
sum += cnt * (cnt - 1) / 2 + cnt
cnt是用来计算非降序的长度的,按理说n≤105n\leq 10^5n≤105,cnt不会爆int,但是。。
上面的代码,sum是longlong,cnt是int。但c艹规定,int∗intint * intint∗int 还是int,然后就爆了。
思路很简单,直接贴一下ac代码吧。
代码:
#include <bits/stdc++.h>
using namespace std;const int maxn = 1e5 + 10;
long long a[maxn];int main()
{int n;scanf("%d", &n);long long cnt = 0;long long sum = 0;for (int i = 1; i <= n; i++){scanf("%lld", &a[i]);if (a[i] >= a[i - 1]) {cnt++;}else {sum += cnt * (cnt - 1) / 2 + cnt;cnt = 1;}}sum += (long long)cnt * (cnt - 1) / 2 + cnt;printf("%lld", sum);return 0;
}
B 小宝的幸运数组
如果一个数组的和能够整除幸运数字k(1≤k≤105)k(1\leq k \leq 10^5)k(1≤k≤105),那么称该数组为幸运数组。给定一个长度为n(1≤n≤105)n(1 \leq n \leq 10^5)n(1≤n≤105)的数组,求这个数组中最长幸运子数组的长度。
为了写这题,我们先看一个简单一点的题目:
给定数组aaa,一个整数kkk。判断aaa中满足ai+aj=ka_i+a_j=kai+aj=k的有多少对?
思路:
两个for循环的复杂度显然是O(n2)O(n^2)O(n2)。如何优化呢?可以用一个hash。对于每一个aaa,在hash table里查询是否有k−ak-ak−a。复杂度可以达到O(n)O(n)O(n)预处理加O(nlogn)O(nlogn)O(nlogn)的n次查询,总复杂度为O(nlogn)O(nlogn)O(nlogn)。
回过来再看这题:既然要求一个数组连续一段的和,那必然要维护前缀和。
然后我们必须用到一些数论知识:(a−b)%m=(a%m−b%m)%m(a-b)\%m=(a\%m-b\%m)\%m(a−b)%m=(a%m−b%m)%m
知道这些,这道题就可做了。一个数组从第lll项到第rrr项的和为:
∑i=lrai=∑i=1rai−∑i=1l−1ai\begin{aligned} \sum_{i=l}^ra_i = \sum_{i=1}^ra_i-\sum _{i=1}^{l-1}a_i \end{aligned} i=l∑rai=i=1∑rai−i=1∑l−1ai
数组的和能够整除kkk,也就是模kkk等于000。
∑i=lrai%k=0=>(∑i=1rai%k−∑i=1l−1ai%k)%k=0\begin{aligned} &\sum_{i=l}^ra_i\%k = 0\\ =>&(\sum_{i=1}^ra_i\%k-\sum _{i=1}^{l-1}a_i\%k)\%k=0 \end{aligned} =>i=l∑rai%k=0(i=1∑rai%k−i=1∑l−1ai%k)%k=0
而∑i=1rai\sum_{i=1}^ra_i∑i=1rai和∑i=1l−1ai\sum _{i=1}^{l-1}a_i∑i=1l−1ai都是数组aaa的前缀和(取模的前缀和)。我们想要数组的和模kkk为000,就相当于求使得aaa在i,ji,ji,j处前缀和相等的最大i,ji,ji,j差值。
判断:一边读取数据,一边算前缀和,如果这个前缀和(注意需要取模)不在map中,那就存进去(把前缀和映射到下标)。如果这个前缀和在map中,就算当前下标和map中前缀和的下标并做差。
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;const int maxn = 1e5 + 10;
long long a[maxn];int main()
{int t;scanf("%d", &t);while (t--) {unordered_map<int, int> mp;int k, n;scanf("%d%d", &n, &k);long long sum = 0;long long dist = 0;mp[0] = 0;for (int i = 1; i <= n; i++) {scanf("%lld", &a[i]);sum = (a[i] % k + sum) % k;if (mp.count(sum)) {dist = std::max(dist, (long long)i - mp[sum]);}else {mp[sum] = i;}}if (dist != 0) {printf("%lld\n", dist);}else {printf("-1\n");}}return 0;
}
G 贪吃的派蒙
给定一个数组,长度为n(2≤n≤105)n(2\leq n \leq 10^5)n(2≤n≤105),数组的第iii个元素为aia_iai,表示编号为iii的角色可以至多领取aia_iai份花酿鸡.数组中最大的一个aka_kak对应的是派蒙,派蒙每次只能拿aka_kak份花酿鸡.花酿鸡一共有kkk份,第一个没有花酿鸡领的人要洗碗.现在大家拍好队,给定的数组就是顺序.大家都想让派蒙洗碗,判断这是否可能.
这都能迫害派蒙是没想到的,不过…迫害的好
现在大家按照这样的顺序排队,其中aka_kak是派蒙:a1,a2,a3,...,ak,...,an−2,an−1,ana_1, a_2,a_3,...,a_k,...,a_{n-2},a_{n-1},a_na1,a2,a3,...,ak,...,an−2,an−1,an.如果用ccc表示第一个人领取花酿鸡的次数,x1,x2,x3,...,ak,...,xn−2,xn−1,xn(1≤xi≤ai,这里除了派蒙每次都是一个定值以外其他的都是不固定的)x_1, x_2,x_3,...,a_k,...,x_{n-2},x_{n-1},x_n(1\leq x_i \leq a_i,这里除了派蒙每次都是一个定值以外其他的都是不固定的)x1,x2,x3,...,ak,...,xn−2,xn−1,xn(1≤xi≤ai,这里除了派蒙每次都是一个定值以外其他的都是不固定的)表示每人每次领取花酿鸡的个数.那么想要派蒙刷碗,也就是到派蒙这刚好没有花酿鸡,需要满足
k=c⋅(x1+x2+...+xk−1)+(c−1)⋅(ak+xk+1+...+xn)=>k−(c−1)ak=c⋅(x1+x2+...+xk−1)+(c−1)⋅(xk+1+...+xn)k = c\cdot (x_1+x_2+...+x_{k-1})+(c-1)\cdot(a_k+x_{k+1}+...+x_n)\\ =>k - (c-1)a_k=c\cdot (x_1+x_2+...+x_{k-1})+(c-1)\cdot(x_{k+1}+...+x_n) k=c⋅(x1+x2+...+xk−1)+(c−1)⋅(ak+xk+1+...+xn)=>k−(c−1)ak=c⋅(x1+x2+...+xk−1)+(c−1)⋅(xk+1+...+xn)
这里的xix_ixi都是有范围的,1≤xi≤ai1\leq x_i \leq a_i1≤xi≤ai带入得:
(c−1)n+k−c≤k−(c−1)ak≤c∑i=1k−1ai+(c−1)∑i=k+1nai=>(c−1)(n+ak)+k−c≤k≤c∑i=1k−1ai+(c−1)∑i=k+1nai+(c−1)ak\begin{aligned} (c-1)n+k-c\leq k - (c-1)a_k\leq c\sum_{i=1}^{k-1}a_i+(c-1)\sum_{i=k+1}^{n}a_i\\ =>(c-1)(n+a_k)+k-c\leq k \leq c\sum_{i=1}^{k-1}a_i+(c-1)\sum_{i=k+1}^{n}a_i+(c-1)a_k \end{aligned} (c−1)n+k−c≤k−(c−1)ak≤ci=1∑k−1ai+(c−1)i=k+1∑nai=>(c−1)(n+ak)+k−c≤k≤ci=1∑k−1ai+(c−1)i=k+1∑nai+(c−1)ak
看着好像挺吓人,但仔细想一想,这个式子中的未知量应该只有ccc.也就是说,这是一个关于c的不等式组(左面右面各一个不等式).判ccc是否有正整数解即可.
继续化简即可得到下式(比上面那个漂亮多了):
k+ak+∑i=k+1nai∑i=1nai≤c≤n+akn+ak−1\begin{aligned} \frac{k+a_k+\sum^{n}_{i=k+1}a_i}{\sum_{i=1}^{n}a_i} \leq c \leq \frac{n+a_k}{n+a_k-1} \end{aligned} ∑i=1naik+ak+∑i=k+1nai≤c≤n+ak−1n+ak
J 这是一题简单的模拟
K 黑洞密码
这两道都是纯模拟,考验底力的题(对我这种fw是真的难,照着官方题解抄都wa了4发)
第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛题解相关推荐
- 第八届“图灵杯”NEUQ—ACM程序设计竞赛个人赛(同步赛)
A题--切蛋糕 龙龙有一块蛋糕,现在他想将蛋糕平均切成k块,分给他的k名hxd.但是不幸的是,因为龙龙不擅长切蛋糕,他每一次只能将一块蛋糕平均分成两份.例如,将一块大小为1的蛋糕分割成两块大小为1/2 ...
- 第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛题解
前言 由于本人比较菜,只会这十道题,如果哪里写的不对,请在评论区指出,剩下的三道题会尽力去补 比赛连接:https://ac.nowcoder.com/acm/contest/27302 A.大学期末 ...
- 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛) 2021.1.30
第八届"图灵杯"NEUQ-ACM程序设计竞赛个人赛(同步赛) B小宝的幸运数组 C上进的凡凡 D Seek the Joker I E Seek the Joker II H 数羊 ...
- 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛)解题报告
第八届"图灵杯"NEUQ-ACM程序设计竞赛个人赛(同步赛) 题目总结 A题 切蛋糕 题目信息 解题思路 如果我们将 1/k展开到二进制的形式,那么就可以计算出 需要 多少块1/( ...
- 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 全题解
比赛链接:这里 第八届"图灵杯"NEUQ-ACM程序设计竞赛个人赛 OP A 切蛋糕 B 小宝的幸运数组 C 上进的凡凡 D Seek the Joker I E Seek the ...
- 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 I 买花
第八届"图灵杯"NEUQ-ACM程序设计竞赛个人赛 I 买花 题目描述: 情人节马上要到了,阳阳想送出n朵花给喜欢的妹妹,他打算提前开始买.但是,因为他有强迫症,所有的花要分k天买 ...
- 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛
第八届"图灵杯"NEUQ-ACM程序设计竞赛个人赛 寒假打的一场比赛,时隔许久对这场比赛还有些许印象,所以特意回来补了这场比赛的题目. 小宝的幸运数组(B题) 题目链接 #incl ...
- 第十届“图灵杯”NEUQ-ACM程序设计竞赛个人赛解题报告
第十届"图灵杯"NEUQ-ACM 题目链接 解题报告 D 文稿修订 思路 代码 F 吃包子 思路 代码 G 数字鉴定 思路 代码 H 线性变换 思路 代码 I 试题排版 思路 代码 ...
- 第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 nn与游戏
第九届"图灵杯"NEUQ-ACM程序设计竞赛个人赛 nn与游戏 原题链接 题目描述 nn最近突然对做游戏非常感兴趣,于是他去找做游戏的xf询问相关话题,而xf此时正好在做一个游戏d ...
最新文章
- HDU 6058 - Kanade's sum | 2017 Multi-University Training Contest 3
- JS ES6中export和import详解
- SQL Server之索引
- 函数不可访问_Java中的不可变总结
- NumPy Essentials 带注释源码 二、NumPy 数组对象
- 虚拟现实设备排行榜(2016年3月27日)
- python类型提示模块包_Python checktypes包_程序模块 - PyPI - Python中文网
- js 浮点数精度问题 可以用accounting.js解决
- 看《墨攻》理解IoC—Spring底层核心
- android的自定义字体,Android中使用自定义字体的方法
- 图解深度学习的笔记:1.MP模型,感知器,BP下的多层感知器
- java 工作流框架都有哪些_java工作流框架有哪些?哪个比较好?
- AndRoid studio创建APP图标
- Frame-relay帧中继网络配置手册
- 无人机通信无线电开放频段
- 如何用计算机弹出斗地主的声音,电脑为什么只有斗地主的时候有声音?
- ITEXT处理pdf详解
- 四通畜牧数据库使用说明
- 直接插入法(java实现)
- 前端学习之认识HTML