Codeforces Round 929 (Div. 3)
A
void solve()
{
ll n, sum = 0;
cin >> n;
for (int i = 1; i <= n; i++)
{
ll x;
cin >> x;
sum += abs(x);
}
cout << sum << endl;
}
B
分类讨论
void solve()
{
ll n, sum = 0;
cin >> n;
vector<ll> a(n + 1, 0);
vector<ll> cnt(10, 0);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
a[i] %= 3;
cnt[a[i]]++;
sum = (sum + a[i]) % 3;
}
if (sum == 0)
cout << "0" << endl;
else if (sum == 1)
{
cout << (cnt[1] ? 1 : 2) << endl;
}
else
cout << "1" << endl;
}
C
暴力枚举
void solve()
{
ll a, b, l;
set<ll> s;
cin >> a >> b >> l;
for (ll i = 1; i <= l; i *= a)
for (ll j = 1; i * j <= l; j *= b)
{
if (l % (i * j) == 0)
s.insert(l / (i * j));
}
cout << s.size() << endl;
}
D
首先考虑如何构造一个可能的方案
按照升序排序
如果最小值只有1个,类似2 3,这样是可以的
但是这样会这种情况 2 2 3,但可行解是3 2 2
注意到只需要找到一个最小值不能整除的数,那么就一定可以
void solve()
{
int n, mi = 1e9;
cin >> n;
map<int, int> mp;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i], mp[a[i]]++, mi = min(mi, a[i]);
if (mp[mi] == 1)
cout << "YES" << endl;
else
{
for (int i = 1; i <= n; i++)
if (a[i] % mi)
{
cout << "YES" << endl;
return;
}
cout << "NO" << endl;
}
}
E
先二分出最小的r满足\(sum[r]-sum[l-1]<=u\)
然后在暴力枚举边界,因为是平方级别的增长,所以大概只需要再跑个200次
void solve()
{
int n, q;
cin >> n;
vector<int> a(n + 1);
vector<ll> s(n + 1, 0);
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
{
s[i] = s[i - 1] + a[i];
}
cin >> q;
for (int i = 1; i <= q; i++)
{
int l, u;
cin >> l >> u;
int lo = l, ri = n;
while (lo < ri)
{
int mid = (lo + ri + 1) >> 1;
if (s[mid] - s[l - 1] <= u)
lo = mid;
else
ri = mid - 1;
}
auto cal = [&](int x) -> ll
{
ll sum = s[x] - s[l - 1];
ll res = (sum * (u - sum + 1 + u)) / 2;
return res;
};
ll ans = ri, mx = cal(ri);
for (int j = ri, cnt = 200; j <= n && cnt; j++, cnt--)
{
ll res = cal(j);
if (res > mx)
mx = res, ans = j;
}
cout << ans << " ";
}
cout << endl;
}
F
注意到往上走是无效的(在i!=m-1)
然后bfs,在最后一列枚举所有可能的答案
void solve()
{
int n, m;
cin >> n >> m;
vector<vector<int>> a(n, vector<int>(m, 0));
vector<vector<int>> dist(n, vector<int>(m, 1e9));
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> a[i][j];
queue<pii> q;
q.push({0, 0});
dist[0][0] = 0;
while (q.size())
{
auto [x, y] = q.front();
q.pop();
int t = dist[x][y];
if (!a[(x + 1 + t) % n][y] && !a[(x + 2 + t) % n][y] && dist[(x + 1) % n][y] == 1e9)
{
dist[(x + 1) % n][y] = t + 1;
q.push({(x + 1) % n, y});
}
if (y + 1 < m && !a[(x + 1 + t) % n][y + 1] && dist[x][y + 1] == 1e9)
{
dist[x][y + 1] = t + 1;
q.push({x, y + 1});
}
}
int ans = 1e9;
for (int i = 0; i < n; i++)
if (dist[i][m - 1] != 1e9)
ans = min(ans, dist[i][m - 1] + min(i + 1, n - i - 1));
cout << ((ans == 1e9) ? -1 : ans) << endl;
}
G
打表发现最多只有8种合法情况,每次加入时判断一下即可
0 0 1 1 0
1 1 0 0 1
0 0 1 1 0
1 1 0 0 1
0 0 1 1 0
0 1 1 0 0
1 0 0 1 1
0 1 1 0 0
1 0 0 1 1
0 1 1 0 0
1 0 0 1 1
0 1 1 0 0
1 0 0 1 1
0 1 1 0 0
1 0 0 1 1
1 1 0 0 1
0 0 1 1 0
1 1 0 0 1
0 0 1 1 0
1 1 0 0 1
0 1 0 1 0
0 1 0 1 0
1 0 1 0 1
1 0 1 0 1
0 1 0 1 0
0 1 0 1 0
1 0 1 0 1
1 0 1 0 1
0 1 0 1 0
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
0 1 0 1 0
1 0 1 0 1
1 0 1 0 1
1 0 1 0 1
1 0 1 0 1
0 1 0 1 0
0 1 0 1 0
1 0 1 0 1
打表代码:
void solve()
{
int n = 5, cnt = 0;
vector<vector<int>> a(n, vector<int>(n, 0));
auto check = [&](int x, int y) -> bool
{
if (x + 2 < n && y + 2 < n)
{
int cnt = 0;
for (int i = 1; i <= 2; i++)
if (a[x + i][y + i] == a[x][y])
cnt++;
if (cnt == 2)
return false;
}
if (x + 2 < n && y - 2 >= 0)
{
int cnt = 0;
for (int i = 1; i <= 2; i++)
if (a[x + i][y - i] == a[x][y])
cnt++;
if (cnt == 2)
return false;
}
if (x + 2 < n)
{
int cnt = 0;
for (int i = 1; i <= 2; i++)
if (a[x + i][y] == a[x][y])
cnt++;
if (cnt == 2)
return false;
}
if (y + 2 < n)
{
int cnt = 0;
for (int i = 1; i <= 2; i++)
if (a[x][y + i] == a[x][y])
cnt++;
if (cnt == 2)
return false;
}
return true;
};
auto dfs = [&](auto dfs, int u) -> void
{
if (u == n * n)
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
if (!check(i, j))
return;
}
cnt++;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
cout << a[i][j] << " ";
cout << endl;
}
cout << endl;
return;
}
int x = u / n, y = u % n;
a[x][y] = 0;
dfs(dfs, u + 1);
a[x][y] = 1;
dfs(dfs, u + 1);
};
dfs(dfs, 0);
cout << cnt << endl;
}
void solve()
{
int n, m, q;
cin >> n >> m >> q;
vector<int> ans(8, 1);
vector<int> r(4, 0);
cout << 8 << endl;
for (int i = 1; i <= q; i++)
{
int x, y, now;
string s;
cin >> x >> y >> s;
now = s[0] == 's' ? 0 : 1;
for (int j = 0; j < 8; j++)
{
int v1 = (j >> 0) & 1;
r[0] = (j >> 1) & 1;
r[1] = (j >> 2) & 1;
if (r[0] == r[1])
r[2] = r[3] = 1 - r[0];
else
r[3] = r[0], r[2] = r[1];
int tar = 0;
if (v1)
{
tar = r[y % 4];
if (x % 2)
tar = 1 - tar;
}
else
{
tar = r[x % 4];
if (y % 2)
tar = 1 - tar;
}
if (now != tar)
ans[j] = 0;
}
cout << count(ans.begin(), ans.end(), 1) << endl;
}
}