2025“钉耙编程”中国大学生算法设计春季联赛(3)
1001
明天补。
看了好久的。。幸好有题解且能看别人代码帮助我理解。
Lucas定理: https://oi-wiki.org/math/number-theory/lucas/
题目要求出满足以下条件的方案数
所以我们需要每个
但是有
如果
否则我们看
若
若
为什么可以跳出循环呢?因为我们实际上,枚举到每一个位,我们加的方案数都是,
但是由于每次我们都设置一位等于
最终答案即为每一个
cpp
constexpr int mod = 998244353;
void ChatGptDeepSeek()
{
/*
101
101
2+1
*/
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i];
ll ans = 1;
for (int i = 1; i <= n; i++)
{
int L;
cin >> L;
if (L >= a[i])
{
int x = 0;
for (int j = 30; j >= 0; j--)
x += (a[i] >> j & 1);
ans = ans * (1 << x) % mod;
continue;
}
int cnt = 0, ok = 1;
for (int j = 30; j >= 0; j--)
{
int x = a[i] >> j & 1;
int y = L >> j & 1;
if (y)
{
int bit = 0;
for (int k = j - 1; k >= 0; k--)
bit += (a[i] >> k & 1);
cnt = (cnt + (1 << bit)) % mod;
if (x == 0)
{
ok = 0;
break;
}
}
}
if (ok)
cnt++;
ans = ans * cnt % mod;
}
cout << ans << '\n';
}1003
看题解还没太看明白。。原来这么妙的。。
统计对于每一个公司,不满足的能力的数量,若全部满足,则是可以下一次面试的公司。把所有的不满足的能力的公司,放进
cpp
using pii = pair<int, int>;
using ll = long long;
void ChatGptDeepSeek()
{
int n, m;
cin >> n >> m;
vector<ll> a(m + 1);
for (int i = 1; i <= m; i++)
cin >> a[i];
vector<vector<int>> c(n + 1, vector<int>(m + 1)), w(n + 1, vector<int>(m + 1));
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
cin >> c[i][j];
for (int j = 1; j <= m; j++)
cin >> w[i][j];
}
vector<priority_queue<pii, vector<pii>, greater<>>> pq(m + 1);
queue<int> q;
vector<int> cnt(n + 1);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (c[i][j] > a[j])
{
pq[j].push({c[i][j], i});
cnt[i]++;
}
}
if (!cnt[i])
q.push(i);
}
int ans = 0;
while (!q.empty())
{
ans++;
int k = q.front();
q.pop();
for (int i = 1; i <= m; i++)
{
a[i] += w[k][i];
while (!pq[i].empty() && a[i] >= pq[i].top().first)
{
auto [_, j] = pq[i].top();
pq[i].pop();
cnt[j]--;
if (!cnt[j])
q.push(j);
}
}
}
cout << (ans == n ? "YES\n" : "NO\n");
}怎么说呢?我本来还在想,他是怎么用到优先队列,怎么更新能力值的。。。非常的牛。
1005
由于城市间是互相可以到达的,所以只需要求联通块的数量。
可以用 DFS 或 并查集。
cpp
constexpr int N = 3e5 + 10;
int f[N + 1];
int find(int x)
{
// cerr << x << " " << f[x] << '\n';
return f[x] == x ? x : f[x] = find(f[x]);
}
void ChatGptDeepSeek()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
f[i] = i;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
// cerr << i << "\n";
if (i - a[i] >= 1) {
// cerr << i - a[i] << " " << find(i - a[i]) << '\n';
f[find(i)] = find(i - a[i]);
// f[i] = f[find(f[i - a[i]])];
}
if (i + a[i] <= n) {
// cerr << i + a[i] << " " << find(i + a[i]) << '\n';
f[find(i + a[i])] = find(f[i]);
// f[i] = f[find(f[i + a[i]])];
}
// for (int j = 1; j <= n; j++)
// cerr << f[j] << " \n"[j == n];
}
int ans = 0;
for (int i = 1; i <= n; i++) {
if (find(f[i]) == i)
ans++;
// cerr << f[i] << '\n';
}
cout << ans - 1 << '\n';
}1010
所以到
cpp
void ChatGptDeepSeek()
{
int n, m;
cin >> n >> m;
vector<int> x(n), y(n);
vector<int> a(4);
a[1] = a[3] = 2e9;
a[0] = a[2] = -2e9;
for (int i = 0; i < n; i++)
{
cin >> x[i] >> y[i];
a[0] = max(a[0], x[i] + y[i]);
a[1] = min(a[1], x[i] + y[i]);
a[2] = max(a[2], x[i] - y[i]);
a[3] = min(a[3], x[i] - y[i]);
}
long long ans = 4e9;
for (int i = 0; i < m; i++)
{
int X, Y;
cin >> X >> Y;
long long c = X + Y, d = X - Y;
long long now = max({c - a[1], a[0] - c, a[2] - d, d - a[3]});
ans = min(ans, now);
}
cout << ans << '\n';
}