AtCoder Beginner Contest 387
A - Happy New Year 2025#
题意#
给定正整数
,求
思路#
模拟
代码#
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 1e6 + 5;
void solve()
{
int a, b;
cin >> a >> b;
cout << (a + b) * (a + b) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T = 1;
//cin >> T;
while (T--)
{
solve();
}
return 0;
}
B - 9x9 Sum#
题意#
有
的网格, 的权是 。给定 ,求所有网格中权不是 的数的和。
思路#
模拟
代码#
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 1e6 + 5;
int cnt[100];
void solve()
{
int n;
cin >> n;
if (n > 81)
{
cout << 2025 << endl;
return;
}
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9; j++)
{
cnt[i * j]++;
}
}
cout << 2025 - cnt[n] * n << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T = 1;
//cin >> T;
while (T--)
{
solve();
}
return 0;
}
C - Snake Numbers#
题意#
定义"蛇数"为:一个不小于
的数,且这个数的十进制首位严格大于其他位的数。给定区间 ,求该区间内的"蛇数"个数
思路#
将上下限转化为两个上限之差,即
。
对于上限,枚举 ,当 的位数小于 的位数以及位数相等但 的首位 的首位时,可以很容易地计算出答案;当位数相等且首位相等时,就枚举 的每一位,当能够判断 不是蛇数或枚举完时结束,注意后者需要多计 ( 本身也是蛇数)。
注意:C++库中的在数据很大时会有精度问题(可能?反正我在这 了一晚上),所以需要自己实现
代码#
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 1e6 + 5;
int _pow(int a, int b)
{
int res = 1;
while (b--)
{
res *= a;
}
return res;
}
int f(int x)
{
if (x < 10)
{
return 0;
}
string s = to_string(x);
int res = 0, len = s.length();
for (int i = 1; i <= 9; i++) // 最高位
{
for (int j = 2; j < len; j++) // 位数
{
res += _pow(i, j - 1);
}
}
for (int i = 1; i < s[0] - '0'; i++)
{
res += _pow(i, len - 1);
}
for (int i = 1; i < len; i++)
{
res += (min(s[i], s[0]) - '0') * _pow((s[0] - '0'), len - i - 1);
if (s[i] >= s[0]) // x不是蛇形数
{
return res;
}
}
return res + 1;
}
void solve()
{
int L, R;
cin >> L >> R;
cout << f(R) - f(L - 1) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T = 1;
//cin >> T;
while (T--)
{
solve();
}
return 0;
}
D - Snaky Walk#
题意#
给定
行 列的网格, 代表起点, 代表终点,#代表障碍物,对每次移动进行限制:当前移动须不同于上次,即上次水平这次就要垂直。求起点到终点需要的最短步数,无解输出
思路#
加上限制的经典
,对于每个点需要额外记录上一次移动的状态,两次 即可得出答案。也可以将 数组开成三维就不用跑两遍了,时间复杂度差不多。
代码#
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 1e3 + 5;
struct node
{
int x, y, step;
bool d; // false代表上一步水平
};
char a[mxn][mxn];
int H, W, sx, sy, gx, gy, ans = LLONG_MAX;
int xdx[] = { 1,-1 };
int xdy[] = { 0,0 };
int ydx[] = { 0,0 };
int ydy[] = { 1,-1 };
void bfs(bool f)
{
queue<node> q;
vector<vector<bool>> vis(mxn, vector<bool>(mxn, false));
q.push({ sx,sy,0,f });
while (q.size())
{
int x = q.front().x, y = q.front().y, step = q.front().step;
bool d = q.front().d;
q.pop();
if (x == gx && y == gy)
{
ans = min(step, ans);
}
if (vis[x][y])
{
continue;
}
vis[x][y] = true;
for (int i = 0; i < 2; i++)
{
// 分水平、垂直两种走
int tx = x + (d ? ydx[i] : xdx[i]);
int ty = y + (d ? ydy[i] : xdy[i]);
if (tx < 0 || ty < 0 || tx >= H || ty >= W || a[tx][ty] == '#')
{
continue;
}
q.push({ tx,ty,step + 1,!d });
}
}
}
void solve()
{
cin >> H >> W;
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
cin >> a[i][j];
if (a[i][j] == 'S')
{
sx = i;
sy = j;
}
else if (a[i][j] == 'G')
{
gx = i;
gy = j;
}
}
}
bfs(false); // 先垂直
bfs(true); //先水平
cout << (ans == LLONG_MAX ? -1 : ans) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T = 1;
//cin >> T;
while (T--)
{
solve();
}
return 0;
}
E - Digit Sum Divisible 2#
题意#
定义正整数
的数位和为其十进制每位数字之和。若一正整数 恰能被其数位和整除,则称它为 ;若 和 都是 ,则称 为 。
现给定,问是否存在 使得 且 ,有则输出任意一个 ,否则输出 。
思路#
参考
站视频
代码#
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 5e5 + 5;
int get_sum(int x)
{
int res = 0;
while (x)
{
res += x % 10;
x /= 10;
}
return res;
}
bool check(int x)
{
return x % get_sum(x) == 0;
}
void pt0(int l)
{
for (int i = 1; i <= l; i++)
{
putchar('0');
}
}
void solve()
{
string n;
cin >> n;
if (n.length() <= 7)
{
int nn = stoll(n);
for (int i = nn; i < 2 * nn; i++)
{
if (check(i) && check(i + 1))
{
cout << i << endl;
return;
}
}
cout << -1 << endl;
return;
}
int f = true;
for (int i = 1; i < n.length(); i++)
{
if (n[i] != '0')
{
f = false;
break;
}
}
if (f)
{
int x = n[0] - '0';
if (x != 9)
{
cout << x << 8 - x;
pt0(n.length() - 2);
}
else
{
cout << "17";
pt0(n.length() - 1);
}
}
else
{
int x = n[0] - '0';
int y = n[1] - '0';
if (x == 8)
{
cout << "107";
pt0(n.length() - 2);
}
else if (x == 9)
{
cout << "17";
pt0(n.length() - 1);
}
else if (x != 1 || x == 1 && y >= 5)
{
cout << x + 1 << 8 - (x + 1);
pt0(n.length() - 2);
}
else
{
cout << "17";
pt0(n.length() - 2);
}
}
}
signed main()
{
/*ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);*/
int T = 1;
//cin >> T;
while (T--)
{
solve();
}
return 0;
}
F - Count Arrays#
题意#
给定长度为
的正整数序列 ,和正整数 。求满足下列条件的正整数序列 的个数(结果对 取模): 且
思路#
参考
站视频
代码#
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 2e3 + 55;
const int mod = 998244353;
int n, m;
vector<int> g[mxn], sg[mxn];
int indeg[mxn], dp[mxn][mxn]; // dp[i][j]表示以i为根的子树,i所在scc中的点对应x的值<=j的方案数
int tot, cnt;
int sz[mxn], id[mxn], dfn[mxn], low[mxn];
stack<int> s;
bool inst[mxn];
void tarjan(int u)
{
dfn[u] = low[u] = ++tot;
s.push(u);
inst[u] = true;
for (auto& v : g[u])
{
if (!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (inst[v])
{
low[u] = min(low[u], dfn[v]);
}
}
if (dfn[u] == low[u])
{
cnt++;
int v;
do
{
v = s.top();
s.pop();
inst[v] = false;
id[v] = cnt;
sz[cnt]++;
} while (v != u);
}
}
void dfs(int u)
{
for (auto& v : sg[u])
{
dfs(v);
}
for (int i = 1; i <= m; i++)
{
int t = 1;
for (auto &v : sg[u])
{
t = t * dp[v][i] % mod;
}
dp[u][i] = (dp[u][i - 1] + t) % mod;
}
}
void solve()
{
cin >> n >> m;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
for (int i = 1; i <= n; i++) // a->b表示a>=b
{
if (a[i] == i) // 自环
{
continue;
}
g[a[i]].push_back(i);
}
// 缩点
for (int i = 1; i <= n; i++)
{
if (!dfn[i])
{
tarjan(i);
}
}
// 建图
for (int u = 1; u <= n; u++)
{
for (auto& v : g[u])
{
if (id[u] != id[v])
{
sg[id[u]].push_back(id[v]);
indeg[id[v]]++;
}
}
}
// dp
int ans = 1;
for (int i = 1; i <= cnt; i++) // 每颗树都跑
{
if (!indeg[i])
{
dfs(i);
ans = ans * dp[i][m] % mod;
}
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T = 1;
//cin >> T;
while (T--)
{
solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效