A、回文括号序列计数
思路:
只有 (…) 形式的才符合题意,但(…)不是回文串
所以只有0的时候才行,其他都不行
代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n;
scanf("%lld", &n);
if (n == 0)
puts("1");
else
puts("0");
}
return 0;
}
C、末三位
思路:
易得…
代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
long long n;
while (cin >> n) {
if (n == 0)
puts("001");
else if (n == 1)
puts("005");
else if (n == 2)
puts("025");
else if (n & 1)
puts("125");
else
puts("625");
}
return 0;
}
D、划数
思路:
将所有除了 cnt 之外的数加起来取模即可,注意特判只有两个数时的特殊情况
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int n, cnt;
int num[N];
int main() {
while (~scanf("%d%d", &n, &cnt)) {
int k = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &num[i]);
if (num[i] == cnt)
k = i;
}
if (n == 2) {
if (k == 1)
printf("%d\n", num[2]);
else
printf("%d\n", num[1]);
continue;
}
num[k] = 0;
for (int i = 2; i <= n; i++) {
num[i] = (num[i] + num[i-1]) % 11;
}
cout << num[n] << "\n";
}
return 0;
}
E、网格
思路:
代码:
F、组合数问题
思路:
①打表上oies查询(瞎搞)
②
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL m = 998244353;
LL mod(LL x, LL y) {
return (x % y + y) % y;
}
LL qpow(LL a, LL b) {
LL ans = 1;
while (b) {
if (b & 1)
ans = ans * a % m;
a = a * a % m;
b >>= 1;
}
return ans;
}
int main() {
LL n;
cin >> n;
n /= 4;
LL x = qpow(4,2*n-1), y = qpow(2,2*n-1);
if (n & 1)
cout << (mod(x, m) + mod(-y, m)) % m;
else
cout << (mod(x, m) + mod(y, m)) % m;
return 0;
}
G、机器人
思路:
因为n的范围很小,所有可以用状压dp求出所有可能的组合顺序的最大值,最终答案取值(20^20 < __int128),所以可用__int128代替高精度
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 20, M = 1 << N;
int a[N], b[N];
__int128 f[M];
inline void print(__int128 x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x/10);
putchar(x%10 + '0');
}
int main() {
int n, x;
cin >> n >> x;
for (int i = 0; i < n; i++)
scanf("%d%d", &a[i], &b[i]);
f[0] = x;
for (int i = 1; i < 1 << n; i++) {
for (int j = 0; j < n; j++)
if (i >> j & 1)
f[i] = max(f[i], f[i-(1<<j)]*a[j] + b[j]);
}
print(f[(1<<n)-1]);
return 0;
}
I、贪吃蛇
思路:
广搜(BFS)板子题
代码:
#include <bits/stdc++.h>
using namespace std;
int n, m;
int xs, ys, xe, ye;
char g[105][105];
bool st[105][105];
int xx[] = {0, 1, 0, -1};
int yy[] = {1, 0, -1, 0};
struct node{
int x, y, s;
};
int main() {
cin >> n >> m;
cin >> xs >> ys >> xe >> ye;
for (int i = 0; i < n; i++)
scanf("%s", g[i]);
queue<node> q;
q.push({xs-1, ys-1, 0});
while (q.size()) {
node t = q.front();
q.pop();
if (t.x == xe-1 && t.y == ye-1) {
cout << t.s * 100 << "\n";
return 0;
}
for (int i = 0; i < 4; i++) {
int dx = t.x + xx[i];
int dy = t.y + yy[i];
if (dx < 0 || dx >= n || dy < 0 || dy >= m)
continue;
if (g[dx][dy] == '#' || st[dx][dy])
continue;
q.push({dx, dy, t.s + 1});
st[dx][dy] = 1;
}
}
puts("-1");
return 0;
}
J、天空之城
思路:
最小生成树板子题 + 哈希存储
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5005, INF = 0x3f3f3f3f;
int n, q, num, idx;
int g[N][N], dist[N];
bool st[N];
map<string, int> mp;
int get(string s) {
if (!mp[s])
mp[s] = ++num;
return mp[s];
}
int prim() {
memset(dist, 0x3f, sizeof dist);
int ans = 0;
for (int i = 0; i < n; i++) {
int t = -1;
for (int j = 1; j <= n; j++)
if (!st[j] && (t == -1 || dist[t] > dist[j]))
t = j;
if (i && dist[t] == INF)
return INF;
if (i) ans += dist[t];
st[t] = true;
for (int j = 1; j <= n; j++)
dist[j] = min(dist[j], g[t][j]);
}
return ans;
}
signed main() {
while (cin >> n >> q) {
memset(st, 0, sizeof st);
string str;
cin >> str;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
g[i][j] = INF;
int s = get(str);
while (q--) {
string a, b;
int c;
cin >> a >> b >> c;
int x = get(a), y = get(b);
g[x][y] = g[y][x] = min(g[x][y], c);
//cout << x << ' ' << y << ' ' << c << endl;
}
int t = prim();
if (t == INF)
puts("No!");
else
cout << t << "\n";
}
return 0;
}