EOJ Monthly 2017.12 (暨 ECNU 12 月内部选拔)解题报告

14 篇文章 1 订阅
1 篇文章 0 订阅

A. 唐纳德先生和假骰子

思路:

计算每一个点数模 p 能达到的概率,直接暴力比较即可

Time limit per test: 1.0 seconds
Memory limit: 256 megabytes
在进行某些桌游,例如 UNO 或者麻将的时候,常常会需要随机决定从谁开始。骰子是一种好方案。普通的骰子有六个面,分别是一点、二点、三点、四点、五点、六点,六面向上的概率相同。由于骰子只能产生六种情况,而实际桌游时,却常常有三到四人,所以,我们在掷骰子时,常常采用两颗骰子,这个「随机的选择」就由骰子向上点数之和直接决定。

我们采用这么一种方案,将向上点数之和对 p(人数)取模,模出来的 0,1,…,p−1 恰好对应 p 个人。但这并不一定是公平的。例如,如果你有算过的话,两枚普通的骰子,在四个人的情形下,就是不公平的。

所以唐纳德先生发明了一种假骰子,这种假骰子也有六个面,但六个面的点数就不再是 1,2,3,4,5,6,而是 a1,a2,a3,a4,a5,a6。如果他精心选择了这六个面的点数,他仍然可以强制公平。

先给出 p 和两枚假骰子六个面的点数,问是否公平。

Input
输入具有如下形式:

pa1 a2 a3 a4 a5 a6b1 b2 b3 b4 b5 b6

第一行一个整数 p (3≤p≤4)。

第二行六个整数,用空格隔开,表示第一枚骰子的点数 a1,a2,a3,a4,a5,a6 (1≤ai≤6)。

第三行六个整数,用空格隔开,表示第二枚骰子的点数 b1,b2,b3,b4,b5,b6 (1≤bi≤6)。

Output
如果公平输出 YES,否则输出 NO。

Examples
input
4
1 2 3 4 5 6
1 2 3 4 5 6
output
NO
input
3
1 2 3 4 5 6
6 5 4 3 2 1
output
YES

package EDU;

import java.util.HashMap;
import java.util.Scanner;

/**
 * Created by jal on 2017/12/8 0008.
 */
public class A {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int p = scanner.nextInt();
        int []a = new int[6];
        int []b = new int[6];
        for(int i= 0; i < 6; i++){
            a[i] = scanner.nextInt();
        }
        for(int i= 0; i < 6; i++){
           b[i] = scanner.nextInt();
        }

        HashMap<Integer,Integer> hashMap = new HashMap<>();
        for(int i = 0; i < 6; i++){
            for(int j = 0; j < 6; j++){
                int t = a[i]+b[j];
                t = t % p;
                if(hashMap.containsKey(t)){
                    int val = hashMap.get(t);
                    hashMap.put(t,val+1);
                }else{
                    hashMap.put(t,1);
                }
            }
        }
        int flag = 0;
        for (Integer i: hashMap.keySet()){
            if(hashMap.get(i) != 36/p){
                flag = 1;
                System.out.println("NO");
                break;
            }
        }
        if (flag == 0) System.out.println("YES");
    }
}

B. 在哈尔滨的寒风中

思路:

虽然限制只能走马步,但我们很容易意识到在足够大的棋盘(例如象棋棋盘)上,马可以达到任何位置。事实上通过简单的验证,可以发现这一大小的下界是
3×4。 于是对于所有 ≥3×4 的棋盘,我们可以断言所有砖之间可以互相到达,此时答案为 (nm2)。 当棋盘大小为 3×3
时,通过简单的模拟可以发现外围的 8 块砖可以互相到达,此时答案为 (82)。 当棋盘大小为 2×n
时,我们发现不同奇偶不同的行/列交替可达,此时有 2 组 ⌊n/2⌋ 的联通块与两组 n−⌊n/2⌋ 的联通块,答案为
2×(⌊n/2⌋2)+2×(n−⌊n/2⌋2)。 当棋盘大小为 1×n 时,没有合法的马步,此时答案为 0。 注意答案可能超过
2147483647,需要使用 long long 类型。

Time limit per test: 1.0 seconds
Memory limit: 256 megabytes
kblack 来到了寒冬中的哈尔滨,哈尔滨的寒风令 kblack 瑟瑟发抖。

世界上最远的距离,是你与宾馆只差一条冰街,而你却忘了穿上秋裤。

kblack 终于冲进了宾馆,宾馆大厅的地板铺满了五颜六色的地砖,可以被看作是一块 n×m 格的棋盘,为了能使冻僵了的双脚尽快暖和起来,kblack 决定在地砖上走动,但是他被速冻的双脚在棋盘地板上只能走马步。

kblack 居然想知道有多少对地砖(无序点对)他可以通过若干步马步互相抵达!
Input
输入包含一行两个正整数 n, m,表示棋盘的大小,保证 1≤n×m≤109 。

Output
输出包含一个整数,表示 kblack 可以通过马步互相到达的无序地砖对数。

Examples
input
1 2
output
0
input
4 2
output
4

C. 易位构词

思路:

显然最多的字母出现次数大于一半的情况是不行的。否则就将每个字母的位置和字母绑定一下,按字母序对结构体进行排序。然后右移「出现最多的字母出现次数」位,再排回来就可以了。时间复杂度 > O(nlogn)。 > > 也可以对 26 个字母进行遍历,把每个字母填到合适的位置。具体细节留给读者思考

Time limit per test: 2.0 seconds
Memory limit: 256 megabytes
易位构词 (anagram),指将一个单词中的字母重新排列,原单词中的每个字母都出现有且仅有一次。例如 “unce” 可以被易位构词成 “ecnu”。在某些情况下,要求重排而成的依然是一个单词,但本题没有这种要求,因为我们根本没有词典。

我们所感兴趣的是,有些单词中的字母进行适当的重排后,可以使得构成的单词每个对应的位置上字母都不一样。例如 “unce” 和 “ecnu”,就有 “u” ≠ “e”, “n” ≠ “c”, “c” ≠ “n”, “e” ≠ “u”。现在给出一个单词,问是否存在这样一个重排。

Input
一行一个单词 s (1≤|s|≤105)。单词完全由 26 个小写英文字母构成。

Output
输出一个单词。如果有多解,输出任意解。如果不存在,输出 impossible。

Examples
input
unce
output
ecnu
input
aaaaaa
output
impossible

D. 唐纳德和他的数学老师

思路

一个很显然的想法是对左边的 n轮和右边个质因数之间建边,便是一个二分图,就是做匈牙利匹配。但是很遗憾,朴素的匹配是错误的,因为存在一个顺序问题。正确的做法是有一次如果不能找到匹配,就直接跳出。这是一个非常经典的问题,具体证明可以自行搜索BZOJ 锦囊问题。求素数可以使用朴素的 O(n−−√) 做法,用素数筛筛过头了可能反而会超时。因为素数不多,但素数的范围比较大,如果直接照抄板子每次都memset 可能会超时,可以打时间戳,或者直接对质数进行离散化。 也可以二分答案直接跑二分图,姿势好一点也能过。

Time limit per test: 1.0 seconds
Memory limit: 256 megabytes
唐纳德是一个数学天才。有一天,他的数学老师决定为难一下他。他跟唐纳德说:「现在我们来玩一个游戏。这个游戏总共 n 轮,每一轮我都会给你一个数(第 i 轮给出的数是 ai)。你每次要回答一个数,是我给出的这个数的质因数,并且你说出的数不能重复。」

因为数学老师是刻意为难,所以这个游戏很有可能不可能进行到最后。但是聪明的数学老师早就已经知道这个游戏最多能进行几轮了。现在他把问题抛给了你,想看看你知不知道。

注意,1 不是质数。

Input
输入具有如下形式:

na1 a2 … an

第一行一个整数 n (1≤n≤3 000)。

第二行 n 个整数用空格隔开,a1,a2,…,an (2≤ai≤106)。

Output
输出游戏最多能进行几轮。

Examples
input
3
7 6 3
output
3
input
5
2 2 2 2 2
output
1

E. 比昨天更多的棒棒糖

思路

Easy 部分可以简单的用 dp[i][j][k]: 买个 i 根,最后一天买 j 根,买 j 根已经 k 天来实现。朴素转移时间复杂度
O(n4) 足够通过,可是没人做。
可以发现,购买棒棒糖,相当于是在做最大容量为 n,物品大小为 x,x+1,…,n 的k重背包,敲好使用 m 元的方案数即是背包容量为 m
的方案数,多重背包 O(n2k) 的复杂度明显是我们无法接受的,考虑使用生成函数优化背包。
∏ni=1(1+xi+x2i+…+x(k−1)i)
=∏ni=11−xki1−xi
=∏ni=1(1−xki)∗∏ni=111−xi
=∏ni=1(1−xki)∗∏ni=1(1+xi+x2i+x3i+…)
答案即是这个生成多项式的 x1 到 xn 的系数之和。
注意到第一部分可以由一次简单的01背包实现,复杂度 O(n2),第二部分可以由一次简单的无限制多重背包实现,复杂度 O(n2)。

Time limit per test: 2.0 seconds
Memory limit: 512 megabytes
唐纳德先生的某女性朋友最近与唐纳德先生同居。该女性朋友携带一 baby。该 baby 酷爱吃棒棒糖,且有一个奇怪的特性:今天吃的棒棒糖一定要比昨天的棒棒糖更多,至少要一样多。如果棒棒糖少了,baby 就会很不高兴;另外如果有连续 k 天棒棒糖的数量都是一样的,baby 也会很不高兴。

唐纳德先生发现他的口袋里只有可怜的 n 元钱,他可以用 1 元钱买 1 根棒棒糖。他想用这些钱逗 baby 开心,这些钱可以不花完。他可以从某一天开始再也不买棒棒糖,把他的女性朋友和 baby 一起送回家;但是他绝对不能让 baby 不高兴,否则他的女性朋友可能对他做一些不和谐的事情。

唐纳德先生想要知道,他总共有多少种买棒棒糖的方案,两种方案不相同当且仅当总天数不相同,或者某一天买的棒棒糖数量不相同。唐纳德先生知道这个问题对于聪明的你实在是太简单了,所以他加了一个附加条件:他第一天必须买棒棒糖,而且至少买 x 根棒棒糖。

Input
一行三个整数 n,x,k。

数据范围约定:

对于 Easy 档:1≤n,x≤100,2≤k≤100。
对于 Hard 档:1≤n,x≤104,2≤k≤104。
Output
输出答案模 998 244 353。

Examples
input
3 1 2
output
4
input
1 1 2
output
1
input
4 2 3
output
4
Note
样例 1:

有四种方案:

第一天 1;
第一天 2;
第一天 3;
第一天 1,第二天 2;
注意第一天和第二天都买 1 是不行的,因为连续两天棒棒糖数量一样,baby 就会很不高兴。

F. 不见了的人口数据

思路:

不知道什么地方挖出来的一道题目,稍微改了下。可能是原题啊。如果有人知道来源的话不妨透露下啊?
Easy 可以简单地跑一遍 Floyd,然后发现是一个线性方程组,然后跑一下 Gauss Elimination。Done!
注意 printf(“%.0f”) 是不对的!会输出 -0!
我们不难留意到一个事实,对于一条边上的两个点,我们做一次减法,得到的就是这条边所连的两个连通块的和的差值。假设该树以 1 为根,我们记第 i
个节点的子树和与除了这个子树外其余节点的和的差为 ti,假如说我们知道整棵树的和 S,那么 S+ti 就是两倍的子树和(可以自行验证)。
那么我们怎么求 S 呢?可以发现,∑ni=2S+ti2 恰好等于 p1,因为距离为 1 的点恰好累积了一次,距离为 i 的点恰好被累积了 i
次。(也可以自行验证)。
那么利用这一个方程我们就可以解出 S,然后再跑一遍 dfs 求每个节点上的值就做好了。时间复杂度 O(n)。
有一个坑点是,本题数据范围没有给,需要从答案的范围反推数据范围,很显然要开 64 位整数。

Time limit per test: 1.0 seconds
Memory limit: 256 megabytes
星光镇的地图是有 n 个点,n−1 条路,这些点从 1 到 n 编号,两两之间都可达;这 n−1 条路的长度都是 1。

这 n 个点是居民聚居点,第 i 个点上有 ai 个居民。去年的时候,星光镇政府曾经做了个人口普查,他们投入了大量的资金,获知了所有节点的 ai,而获知的目的,就是为新政府大楼的选址做准备的。由于新政府大楼一定会建在一个居民聚居点上,所以星光镇政府求出了对于每个聚居点 j 的「政府大楼收益评估函数」:

pj=∑i=1ndis(i,j)⋅ai
其中 dis(i,j) 是 i,j 号点之间的最短距离。特别的,dis(i,i)=0。

新政府大楼造好了,政府自然而然地进行了一些证据销毁工作,同时「一不小心」销毁了重金得来的人口普查数据:也就是说 ai 都丢失了。但是巧的是,所有的收益评估函数值 p1,p2,…,pn 竟然都留存了下来。星光镇数据研究所唐纳德博士表示:「从这些函数值中,我们完全可以将所有的人口数据都反求出来。」但是唐纳德博士,虽然是一个著名的数学天才,但却很有可能是一个假博士,他这话自然不能当真。所以当星光镇政府又要造一个新的政府大楼,又要用到这些人口数据时,他们花费了巨资进行再调查。

身在异国的你听到此事后大笑不止,利用 p1,p2,…,pn 轻轻松松地求出了 a1,a2,a3,…,an。

Input
输入具有如下形式:

nu1 v1⋮un−1 vn−1p1 p2 … pn−1 pn

第一行一个整数 n。

接下来 n−1 行,每行两个整数 ui,vi (1≤ui,vi≤n),分别表示这 n−1 条路。这 n−1 条路都可以双向通行。两个居民聚居点之间不会有多条路相连,也不会有一条路的两端连接了同一个居民聚居点。

最后一行,用空格隔开的 n 个整数 p1,p2,…,pn,表示收益评估函数。

数据保证答案有解,并且满足 0≤a1,a2,…,an≤1 000。

数据规模约定:

对于 Easy 档:1≤n≤100。
对于 Hard 档:1≤n≤250 000。
Output
依次序输出 a1,a2,…,an。如果有多解,输出任意解。

Examples
input
2
1 2
11 9
output
9 11
input
6
1 2
1 3
3 4
3 5
5 6
32 45 19 28 16 21
output
0 1 2 3 4 5

G. 唐纳德与子串

思路:

考虑离线处理。将所有查询和母串相连建后缀数组。对于每一个查询,在排好序的后缀数组中恰好有一段相对应,可以二分求得 L,R。问题就转换为在
L,R
区间内有多少后缀的下标在查询区间范围内的。这是一个非常经典的区间问题。继续考虑离线处理,从大往小将数插入,然后使用树状数组轻松解决。时间复杂度
O(nlogn)。
事实上本题的做法非常套路,所以过得人也比 F 多(???)。
据验题人说暴力加疯狂特判也能过,而且玄学优化不可卡。暴力姿势太大,比不来。

Time limit per test: 1.0 seconds
Memory limit: 256 megabytes
子串的定义是在一个字符串中连续出现的一段字符。这里,我们使用 s[l…r] 来表示 s 字符串从 l 到 r(闭区间)的子串。在本题中,字符串下标从 0 开始。显然,对于长度为 n 的字符串共有 n(n+1)2 个子串。

对于一个给定的字符串 s,唐纳德给出 q 次询问,第 i 次询问包括三个参数 li,ri,zi,问在 s[li…ri] 的所有子串中共有多少个恰好为 zi。

Input
输入具有如下形式:

sql1 r1 z1l2 r2 z2⋮lq rq zq

第一行一个字符串 s。

第二行一个整数 q。

接下来每行:首先两个整数 li,ri (0≤li≤ri<|s|),然后是一个非空字符串 zi。整数和整数,整数和字符串间以单空格隔开。

字符串中只会出现 26 个小写英文字母。

数据规模约定:

对于 Easy 档:1≤|s|≤100,q≤∑|zi|≤100。
对于 Hard 档:1≤|s|≤105,q≤∑|zi|≤105。
Output
对于每次询问,输出一个整数,表示答案。

Examples
input
thisisagarbagecompetitionhahaha
5
0 30 a
1 5 is
25 30 hah
6 12 ag
7 12 ag
output
6
2
2
2
1

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值