2019 ICPCChina Shannxi Province Programming Contest

A.

n是50位的数,f(i)=i中出现次数最多的最大的数,求f(1)-f(n)的和。

首先显然按位考虑,考虑从大到小的第i位开始比原数小,枚举这位是j,那么后面的若干位可以选0-99999…,再枚举产生贡献的数字是k,那么dp即可得到将这后若干位分给0-9使得k比其他都多的方案数。然后有前导零的情况要特殊处理,具体就是枚举所有不足原数位数个9,用上述dp计算,时限有点卡,所以打个长度50的表。

B.

一个图,每个点指向另一个点,问有没有方法从一个点出发沿着边走能遍历所有点。
显然点数为n,边数为n的情况下,要遍历所有点必须有一条长度为n的链,最后一个点随便指向谁。那么如果有一个点入度为0,则必须要从这个点能走到全部点;如果所有点均有入度,那么应该从任一点出发都能遍历全图。除此之外均为非法。

C.

只含0689的字符串,你必须且只能把某一段翻转(不仅是位置对调,6和9也会反过来)。问可以产生多少种不同的字符串。

考虑转一段区间的贡献,如果转完以后两头的字符都未变化,那么反转此区间和翻转比他左右短一点的字符完全一样,故没有贡献。具体的,只有反转区间的l,r两点变得不同才能产生贡献。这样做一定不会算重,因为如果反转另一个这样的区间并使l,r产生相同变化,一定会导致l,r之外的点也产生变化。因此我们实际就是要算“两个点互换后不同的位置对数”。但是注意到,这样算会漏算有时翻转串不变的情况,这种情况我们只要判断有没有0和8,以及有没有相邻的69,如果有,答案++。

D.

A,B,C三个点在二维平面上,A要去C,速度为a,B可以开车去接A,速度始终为b,问A最快什么时候到C(B可以不用到达),另外两人只能沿坐标轴方向移动。
方便写起见,在以下答案中取min:
1.A直接走到C
2.设D为AB作为对角的矩形中离C最近的点,
(1)如果A会先到D,则为B到C距离除以b
(2)B先到D,则A和B先相向而行,然后剩下的距离为A到C的距离-这段时间A走的距离。

E.

n盏灯或亮或灭,一次操作使区间内灯全灭,问要用k次以内的操作使灯全灭,最短的区间长度为多少。
显然直接二分,然后模拟每次关最左边的亮的。

F.

已知a+b%x=c
问x
如果a+b==c,输出无穷大即可
如果a+b-c<=a||<=c 输出-1
输出a+b-c

G.

给了一个01网格,你可以任意按某条线对折,要求是折过来重合的部分01也重合,最后问使0的连通块个数最少是多少个。
贪心认为能折就折不会使答案更劣,因此从左到右,从右到左,从上到下,从左到右分别尽量折(用马拉车或者hash等算匹配就行)。然后算连通块个数。场上数据放过去了,但是听说不是正解Orz。

H.

1-n(1e5),可以把两个gcd不为1的数分为一组,问最多分多少组。
把每个数按最大质因子分组,可以发现的是,因为是1-n,所以一种最大质因子下,如果有x个数,那么必然第一个是含2的(因为有其他因子那也肯定有最小的2).所以每种最大质因子要么可以自身两两匹配,要么剩一个偶数,要么只有一个本身(大于二分之n)。那么把剩下的那个偶数和最大质因子为2的放在一起再次两两配对,所得答案即为最优。

I.

一棵无根树(1e5),每条边有一个字母,问有多少个点当根可以使他便乘合法的trie树。
trie树不合法是因为一个点的子节点中有两条相同字母边。
单独考虑每个点,若他有一种字母边达到三条,或者有两种字母边达到两条,整棵树就不可能合法,输出0.
然后,显然的,对于相同的那两条字母边,根在任意一边都行。这个(可以)标记维护起来当然可以,但是更好写的方式是除了这两条边以外的方向全部“不行”。实现的话,先随便找个根,然后处理每个点的贡献,相当于是把从那个点出发的几个方向上的点全部非法,可以用dfs序维护,因为操作一定是把一个子树置零,或者把子树外置零,所以相当于在dfs序上的区间。然后排个序扫描线即可,当然你想用线段树之类的直接操作也行。

J.

n(1e5)个区间,从每个区间中选一个数,问他们and起来最大值是多少。
从高位到低位按位确认,类似数位dp。如果一位可以全填1,则一定全填1,然后修改区间的下界。如果不能都填1,那么应该尽量填0,并修改上界,这样可以使后面有更多机会填1.

K.

1e5规模的图,有k个出口,一开始你在1号点。想从任意一个出口出去。
i号点有di只怪兽,只有当你【离开】i号点时,他们会分别堵住一条出路。怪兽会尽量不让你到达出口,问在你和怪兽都采取最优策略的情况下最快要多久到达出口。
乍一看不同城市之间的怪兽不太好协调,但是仔细一想怪兽肯定是堵到出口最近的那几个路。
因此从出口倒着往回跑dijkstra,如果当前点是能到的最近点,那么你可能从周围其他未被扩展的点过来。你对他们贡献一种dis[now]+边权的“出口方案”。在每个点开一个堆维护所有“出口方案”。可以发现只有当i号点有超过di种方案时怪兽才会堵不过来,且他们会堵住最近的di种方案。所以当扩展后目标点的第di+1种方案更新时把i入队。显然,这么做对于怪兽和你都是对的。

L.

f(i)=i的每一位相乘。
给出l,r(1e9),问 Π i = l r f ( i ) \Pi_{i=l}^{r}f(i) Πi=lrf(i)
如果r和l跨过了一个10,显然就是0.
不然就暴力一乘。

C++中的`.emplace_back()`函数是从C++11起新增到vector中的方法,它可以在vector的末尾直接构造一个元素,而不需要先构造一个临时对象再将其拷贝或移动到vector中。`.emplace_back()`函数的函数声明为:`template<class... Args> void emplace_back( Args&&... args );`,它可以接受任意数量和类型的参数,并将这些参数传递给元素的构C++11中的emplace_back函数是STL容器vector的一个成员函数,它可以在vector的末尾直接构造一个元素,而不需要先创建对象再添加。与push_back函数不同,emplace_back函数可以直接传递构造函数的参数,而不需要先创建一个对象。这样可以避免不必要的拷贝和移动操作,提高程序的效率。同时,emplace_back函数还支持可变参数模板,可以传递任意数量和类型的参数。 举个例子,假设我们有一个结构体Youbain,它有三个成员变量:_contry、_privence和_number。我们可以使用emplace_back函数来向vector中添加一个Youbain对象,如下所示: ``` vector<Youbain> el; el.emplace_back("China", "Shannxi", 610000); ``` 这样就可以直接在vector的末尾构造一个Youbain对象,而不需要先创建一个对象再添加。同时,我们还可以使用push_back函数来添加一个Youbain对象,如下所示: ``` el.push_back(Youbain("China", "Beijing", 10000)); ``` 这样就需要先创建一个Youbain对象,再将其添加到vector中。可以看到,使用emplace_back函数可以避免不必要的拷贝和移动操作,提高程序的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值