A. 最小的01数字串
题意:寻找满足条件的最小正整数M,使得N乘以M的结果仅包含0和1
设这个数为x,满足x=NM,且x仅有0或1组成
因此,枚举这个x就可以了
n=int(input())
if n==1:print(1,1,1);exit()
from collections import*
q=deque([(1,'1')]);v={1}
while q:
r,s=q.popleft()
if not r%n:print(n,int(s)//n,s);exit()
for c in'01':
t=(r*10+int(c))%n
if t not in v:v.add(t);q.append((t,s+c))
这里导入 deque
用于 BFS 队列
好吧这是不压行版
# 读取输入整数 n
n = int(input())
# 如果 n = 1,直接输出最小解
if n == 1:
print(1, 1, 1)
exit()
from collections import deque # 导入队列
# 队列用于 BFS,初始状态是 (余数 1, 数字 "1")
q = deque([(1, '1')])
# 用于记录已经出现过的余数,防止重复搜索
v = {1}
# BFS 搜索
while q:
r, s = q.popleft() # 从队列中取出当前的余数 r 和对应的数字字符串 s
# 如果当前余数 r 能整除 n,说明找到了满足条件的最小数字 s
if not r % n:
print(n, int(s) // n, s) # 输出 n, M=int(s)//n, 以及 s 本身
exit() # 结束程序
# 生成新的状态:在当前数字 s 后面添加 '0' 或 '1'
for c in '01':
# 计算新的余数,避免处理大整数:
# (原余数 * 10 + 新的数字) % n
t = (r * 10 + int(c)) % n
# 如果这个余数 t 之前没有遇到过,就加入队列继续搜索
if t not in v:
v.add(t) # 记录新的余数
q.append((t, s + c)) # 把新的状态 (t, s+c) 加入队列
B. 【202202--白银组--A】求和
题目不让用数组,于是推导一下这个公式
S = \sum_{i=1}^n \left( a_i \times \sum_{j=1}^i a_j \right)
易得
a_i \times \left( a_1 + a_2 + \dots + a_i \right) = a_1a_i + a_2a_i + \dots + a_i^2
因此,有
S = \sum_{i=1}^n \sum_{j=1}^i a_i a_j = \sum_{i=1}^n a_i^2 + \sum_{i > j} a_i a_j
又因为
\left( \sum_{i=1}^n a_i \right)^2 = \left( a_1 + a_2 + \dots + a_n \right) \times \left( a_1 + a_2 + \dots + a_n \right)
= \sum_{i=1}^n a_i^2 + \sum_{i \neq j} a_i a_j \\ (乘法分配律)
且对于
\sum_{i \neq j} a_i a_j
可以拆成
\sum_{i > j} a_i a_j + \sum_{i < j} a_i a_j
由于求和是对称的,即对于每一对 (i, j),当 i > j 时有 a_i a_j,当 i < j 时也有相同的 a_j a_i,所以:
\sum_{i \neq j} a_i a_j = 2 \sum_{i > j} a_i a_j
所以
\left( \sum_{i=1}^n a_i \right)^2 = \sum_{i=1}^n a_i^2 + 2 \sum_{i > j} a_i a_j.
解得
\sum_{i>j} a_i a_j = \frac{\left( \sum_{i=1}^n a_i \right)^2 - \sum_{i=1}^n a_i^2}{2}
代回原式,得
S = \sum_{i=1}^n a_i^2 + \frac{\left( \sum_{i=1}^n a_i \right)^2 - \sum_{i=1}^n a_i^2}{2}
整理,得
S = \frac{\left( \sum_{i=1}^n a_i \right)^2 + \sum_{i=1}^n a_i^2}{2}
因此,有
n, mod, inv = int(input()), 998244353, (998244353 + 1) // 2
s = ss = 0
arr = input().split()
for i in range(n):
a = int(arr[i])
s = (s + a) % mod
ss = (ss + a * a) % mod
print((s * s + ss) * inv % mod)
C. 【202202--白银组--C】整数
不难发现超数是能被 n 整除的所有自然数,数学上对应于n 的倍数集合。
子数是包含 n 的倍数的所有自然数,数学上对应于n 的因数集合。
公超数是 a 和 b 的最小公倍数的倍数。
公子数是 a 和 b 的最大公约数的倍数。
因此
#include<bits/stdc++.h>
using namespace std;
int main() {
long long a,b;
cin>>a>>b;
long long g=__gcd(a,b);
cout<<g<<' '<<a*b/g;
}
D. 【202202--白银组--D】图片
这题就是纯模拟
数据量非常小
#include<bits/stdc++.h>
using namespace std;
int main() {
int T;
cin >> T;
while (T--) {
int r, c, n, m, ans = 0;
cin >> r >> c;
vector<string> A(r);
for (int i = 0; i < r; i++) cin >> A[i];
cin >> n >> m;
vector<string> B(n);
for (int i = 0; i < n; i++) cin >> B[i];
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
bool ok = 1;
for (int k = 0; k < n; k++) {
for (int l = 0; l < m; l++) {
int x = i + k - n / 2, y = j + l - m / 2;
if (x >= 0 && x < r && y >= 0 && y < c) {
if (A[x][y] == '#' && B[k][l] == '#') {
ok = 0;
}
}
}
}
if (ok) ans++;
}
}
cout << ans << endl;
}
}