AtCoder Beginner Contest 387



A - Happy New Year 2025#

题意#

给定正整数A,B,求(A+B)2

思路#

模拟

代码#

点击查看代码
#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#

题意#

9×9的网格,(i,j)的权是i×j。给定n,求所有网格中权不是n的数的和。

思路#

模拟

代码#

点击查看代码
#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#

题意#

定义"蛇数"为:一个不小于10的数,且这个数的十进制首位严格大于其他位的数。给定区间[L,R],求该区间内的"蛇数"个数

思路#

将上下限转化为两个上限之差,即 ans([L,R])=ans([10,R])ans([10,L1])
对于上限R,枚举x,当x的位数小于R的位数以及位数相等但x的首位<R的首位时,可以很容易地计算出答案;当位数相等且首位相等时,就枚举R的每一位,当能够判断R不是蛇数或枚举完时结束,注意后者需要多计1(R本身也是蛇数)。
注意:C++库中的pow在数据很大时会有精度问题(可能?反正我在这wa了一晚上),所以需要自己实现pow

代码#

点击查看代码
#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#

题意#

给定HW列的网格,S代表起点,G代表终点,#代表障碍物,对每次移动进行限制:当前移动须不同于上次,即上次水平这次就要垂直。求起点到终点需要的最短步数,无解输出1

思路#

加上限制的经典BFS,对于每个点需要额外记录上一次移动的状态,两次BFS即可得出答案。也可以将vis数组开成三维就不用跑两遍了,时间复杂度差不多。

代码#

点击查看代码
#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#

题意#

定义正整数n的数位和为其十进制每位数字之和。若一正整数n恰能被其数位和整除,则称它为goodinteger;若aa+1都是goodinteger,则称(a,a+1)twingoodintegers
现给定n,问是否存在twingoodintegers使得naa+12n,有则输出任意一个a,否则输出1
n10100000

思路#

参考B站视频BV16brTYaEZ5

代码#

点击查看代码
#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#

题意#

给定长度为n的正整数序列A(Ain),和正整数m。求满足下列条件的正整数序列x的个数(结果对998244353取模):ximxixAi(1in)

思路#

参考B站视频BV16brTYaEZ5

代码#

点击查看代码
#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;
}



比赛链接 https://atcoder.jp/contests/abc387

posted @   _SeiI  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示