这篇博客记录下atcoder上的棕色难度的刷题记录;
ABC190 C - Bowls and Dishes
题解
这里由于\(k\)最大只有\(16\),因此可以用暴力,这里使用二进制进行枚举,第\(i\)位为0表示,选择将球放在\(C_i\)中,否则放在\(D_i\)中;之后判断\(m\)个\(condition\)满足了多少个,然后更新最大值;
code
1 |
|
ABC190 D - Staircase Sequences Editorial
题解
题目即让我们求满足\(\frac{(A+B)(B-A+1)}{2}=2N\)的\((B-A+1)\)的种类数乘以\(2\);并且一个重要的隐含条件是,\(A+B\)与\(B-A+1\)必定是一奇一偶;
code
1 |
|
ABC189 C
题解
题目的意思是这样的,给定一个长度为\(n\)的序列\(a\),求\(\max((l-r+1)\times \min(a_l\dots a_r))\)
这个题目其实可以暴力,复杂度\(O(n^2)\),也可以用单调栈;对于\(a[i]\),分别求除左边和右边比他小的数的位置,\(l_i,r_i\),那么以\(a[i]\)为最小值的最长区间为\(\left[l_i + 1, r_i - 1\right]\);然后不断更新答案即可;
code
1 |
|
ABC189 D
题解
题意:给定\(n\)个字符串\(s_1\dots s_n\),求序列\((x_0\dots x_n)\)的个数,该序列保证\(y_n\)结果为True
;其中\(y_0=x_0\),如果\(s_i\)为AND
,那么\(y_i=y_{i-1}\&x_i\),若\(s_i\)为OR
,那么\(y_i = y_{i - 1}|x_i\);其中\(x_i\)只能为True
或False
;
令\(dp[i][0/1]\)表示前\(i\)个变量的结果为True
或False
的情况下的序列的个数;
code
1 |
|
ABC187 D
题解
这题不能\(A_i+B_i\)贪心,因为某一步的贪心并不能保证全局的最优;实际上每次选择都会影响到后序的选择情况;
按\(2A_i+B_i\)贪心的从大到小选是可行的;
比如
1 | //按A+B排 |
code
1 |
|
ABC186 D
题解
对于长度为\(n\)的序列\(A\),求\(\displaystyle{\sum_{i=1}^{N-1}\sum_{j=i+1}^{N} |A_i-A_j|}\);
即求所有任意两个元素差绝对值的和;
实际上这个结果跟\(A\)的排列顺序无关,因此如果A是升序的;
那么即求,对任意的\(i\),\(\sum_{j=i+1}^{N}|A_i-A_j|=(\sum_{j=i+1}^{N}A_j)-(N-i)A_i\)
code
1 |
|
ABC185 D
code
1 |
|
ABC183 D
题解
往一个全\(0\)序列进行区间加的操作,最后问是否有某个位置的和大于\(w\);这里可以使用树状数组,之后查询每个位置的和即可;或者直接差分更简单;小心爆\(int\)
code
1 |
|
ABC182 D
code
1 |
|
ABC181 D
题解
因为\(1000=8\times 125\),因此\(10^3、10^4\dots\)都是\(8\)的倍数,实际上只需要判断最后\(3\)位即可;
\(1000\)以内\(8\)的倍数可以枚举出来,对于每个数,判断\(s\)中是否有字符能够组成它即可;
code
1 |
|
ABC178 C
题解
容斥原理,直接求包含\(0\)和\(9\)的不好求,分别求出仅不包含\(0\)和仅不包含\(9\)的可能数,在求出不包含\(0\)和\(9\)的可能数;
code
1 |
|
ABC177 D
题解
这是一个并查集计数的问题,实际上就是需要我们求所有连通量中,最大的那个包含多少个元素;
code
1 |
|
ABC175 C
code
1 |
|
ABC173 C
题解
数据非常的小,可以暴力;用二进制枚举行与列的所有的选择的情况,然后统计#
的数量为\(k\)的情况;
code
1 |
|
ABC169 C
题解
这点需要注意,\(double\)在内存中都是近似存储的(\(\text{IEEE754}\)),比如\(0.1\)并不能精确的表示; 因此可以想象如果把这个\(double\)再乘上一个很大的数,那么这其中的误差就会被放大;这里可以将\(double\)当作一个字符串,将小数部分按位计算,或者使用std::round
;
code
1 |
|
ABC165 D
题解
定义\(f(x) = floor(\frac{Ax}{B}) − A × floor(\frac{x}{B})\),那么有\(f(x + B) = f(x)\);那么不妨假设\(0\leq x\leq n - 1\),则\(f(x)=floor(\frac{Ax}{B})\),此时由于\(f(x)\)是单调不减的,则\(x\)越大越好,那么当\(x\)取\(min(B-1,N)\)时,\(f(x)\)最大;
code
1 |
|
ABC159 D
题解
首先统计每个数字出现次数,那么从\(N\)个数字中取两个相同的总的方法数也就知道了;对于\(A[i]\)来说,要求从\(A[i]\)外的\(N-1\)个数字中取2个相同的,只需要拿总的方法数减去\(A[i]\)的贡献即可;
code
1 |
|
ABC150 C
题解
给了我们长度为\(n\)的两个\(1\)到\(n\)全排列,然后需要我们求它们字典序差的绝对值;一开始的想法是,由于\(n\)最大是\(n\),那么可以求出\(1\)到\(n\)所有全排列,然后利用\(hash\)记录字典序(\(c++\)的next_permutation
是按字典序递增生成排列的),之后求差;
看了题解,不一样的是,题解是把排列看成整数,然后分别求出所有排列中,小于排列\(a、b\)对应整数的排列有多少个,然后相减;
这里又用了一下\(python\),\(python\)的\(itertools\)提供了很多函数,其中的\(itertools.permutation\)需要一个可迭代对象作为参数(可以是字符串!);
1 | import itertools |
1 | import itertools |
code
1 | import itertools |
ABC149 D
题解
对于给定的\(A、B、X\),我们需要求满足\(A\times N+B\times d(N)\leq X\)的最大的N,\(d(N)\)是\(N\)有多少位,N的范围是\(1\)到\(10^9\);
我们可以枚举\(d(N)\),这样\(N\)的范围就确定了,再枚举\(N\)找到满足条件的\(N\);
code
1 | def check(n, x): |
ABC137 D
题解
一开始是想直接对\(value\)进行贪心,但是会有这样一个问题比如两个工作2 1
和1 2
,\(M\)是3,如果优先选\(value\)大的,那么1 2
就不能第一个,那么如果选它,就只能在第\(2\)天做,那它的报酬只能在第\(4\)天获得(大于\(M\));
通过对时间排序(也就是延迟获得报酬的时间尽量小),从最后一天往前,筛选出最迟完成时间在同一天的工作,从中选出价值最大的;
如果在最后一天做,只能做完成后\(1\)天就可以获得报酬的工作,倒数第二天做,只能做完成后\(1\)或\(2\)天就可以获得报酬的工作,\(\dots\);
code
1 |
|
ABC143 D
题解
给定一个序列,需要求能够组成三角形的三元组的个数;考虑三条边从小到大的三条边\(a、b、c\),如果\(a、b\)确定了,那么我们只需要\(c\lt a + b\);那么我们枚举\(a、b\),求满足\(b\le c\lt a + b\)的\(c\)的个数,可以用树状数组,或者直接二分也可以;
code
1 | import bisect |
1 |
|