- A
- B
- C
- D
- 法一
- 更好的法二
- 代码
- E
- 实现代码
- 参考链接
传送门
CSDN传送门
juejin传送门
作者:hans774882968以及hans774882968
A题意:有三种类型的客人,他们依次到来,一种反对者,一种支持者,还有一种观望者,即根据当前情况,如果反对数 > 支持数,就投反对,反之投支持的人。现在你有两台服务器,你可以选择给当前来到的客人展示其中一台服务器,问你最多可以获得多少票支持。
有两台服务器,所以把所有dislike都集中到一台服务器即可(提纯是吧郎)。
from collections import defaultdict
for _ in range(int(input())):
n = int(input())
a = list(map(int, input().split()))
print(sum([1 if v == 1 or v == 3 else 0 for v in a]))
B
题意:给三个数a,b,c,让你找到两个数x和y,使得x,y,gcd(x,y)这三个数的位数分别是a,b,c。
最简单的方法是,令x和y都有c-1个0,则只需要求x0和y0,使得两者满足位数条件且gcd(x0,y0) = 1。考虑"1" * (a-c+1)和"1" + "0" * (b-c),由辗转相除法可知它们确实互质。
from typing import List
from collections import defaultdict
for _ in range(int(input())):
x, y, z = map(int, input().split())
print("1" * (x - z + 1) + "0" * (z - 1), "1" + "0" * (y - 1))
# c = "1" + "0" * (z - 1)
C
题意:从前往后给你n张卡片,每个卡片都有一个颜色,然后有m次询问,每次询问找到最前面的这个颜色的卡片,输出它的下标,然后把它放到最开头去。
看上去是数据结构,其实是很简单的性质题。我们发现,最前面的某颜色卡片放到最开头后,仍然是最前面的。所以不是最前面的卡片都没有意义,只需要维护每种颜色最前面的卡片的下标。故引入a[x]表示颜色x的最靠前面的下标。设当前询问颜色为t,则修改操作是:对a中所有小于a[t]的数加1,然后a[t]变为1。
因为颜色值域才50,所以可直接暴力。
#includeDusing namespace std; typedef long long LL; typedef pair pii; #define rep(i,a,b) for(int i = (a);i <= (b);++i) #define re_(i,a,b) for(int i = (a);i < (b);++i) #define dwn(i,a,b) for(int i = (a);i >= (b);--i) const int N = 50 + 5; int n, q, a[N]; void dbg() { puts (""); } template void dbg (const T &f, const R &... r) { cout << f << " "; dbg (r...); } template inline void read (Type &xx) { Type f = 1; char ch; xx = 0; for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar() ) if (ch == '-') f = -1; for (; ch >= '0' && ch <= '9'; ch = getchar() ) xx = xx * 10 + ch - '0'; xx *= f; } void read() {} template void read (T &x, R &...r) { read (x); read (r...); } int main() { read (n, q); int mx = 0; rep (i, 1, n) { int x; read (x); mx = max (mx, x); if (!a[x]) a[x] = i; } rep (i, 1, q) { int t; read (t); printf ("%d%c", a[t], " n"[i == q]); rep (j, 1, mx) if (a[j] < a[t]) a[j]++; a[t] = 1; } return 0; }
题意:让你用从'a'开始的前m个字母,构造一个字符串S(1-indexed),使得满足1<=i 看了参考链接1,思路是直接贪心地保证当前看上去比较优,即枚举所有候选字母c,选择las + c出现次数最少的(实现上,用一个哈希表,把长度为2的字符串映射成m进制数作为key)。若有多个最少的,应选择最大的字母,因为这样能最大化预留后续的选择空间。这样求出的字符串会是zzyzxzw...的形式,字典序很大。 看第一个样例9 4的答案aabacadbb,对以上方法求出的字符串进行一个简单的映射即可得到。下面的代码使用了那个额外的映射。 法一求出的字符串进行简单映射后,就很有规律,以m = 4为例:aabacadbbcbdccdd。不断复制直到长度大于等于n即可。 法一 法二 题意:n * m矩阵,由o和*组成,o可以涂成红或蓝色。多米诺骨牌是一个1 * 2的矩阵,红色格子只能横着放骨牌,蓝色格子只能竖着放骨牌。这样就很容易求一种涂色方案可放置的最大骨牌数,求所有2 ^ w种方案可放置的最大骨牌数的和,模998244353。 首先看一种涂色方案可放置的最大骨牌数,就是红色格子以一个横条为单位,蓝色格子以一个竖条为单位来求,非常简单。这里体现的性质:任意两个横条、任意两个竖条和横条与竖条之间都互不干扰。又注意到矩阵转置一下,竖条就变成横条。因此我们直接求出每个横条的贡献,求和即可。 设一个横条所有涂法的最大骨牌数之和为v(不考虑矩阵的其他部分),则把矩阵其他部分考虑进来后,该横条对答案的贡献为v * 2^tot,2^tot表示矩阵的其他部分的涂色方案总数。 最后只需要知道v的求法。横条唯一的特征就是格子数,因此设dp[i]为i个格子的横条的所有涂法的最大骨牌数之和。边界:dp[0] = dp[1] = 0。转移:若第i个格子涂蓝色,则该格子作废,取dp[i-1]。若第i个格子涂红色,则:(1)第i-1个格子涂蓝色,取dp[i-2]。(2)第i-1个格子取红色,则最后两个格子所放置的骨牌对前面格子的2^(i-2)种涂法各有1贡献,取dp[i-2] + 2^(i-2)。故dp[i] = dp[i-1] + 2*dp[i-2] + 2^(i-2)。这种构造题我怎么可能会嘛#include
from collections import defaultdict
n, m = map(int, input().split())
ans = ""
for i in range(m):
ans += chr(97 + i)
for j in range(i + 1, m):
ans += chr(97 + i) + chr(97 + j)
while len(ans) < n:
ans += ans
print(ans[:n])
E
#include
参考链接



