Codeforces Round 896 (Div. 2)
C
题意:
构造一个 n * m 的矩阵,要求每一行都是[0, m - 1]的排列,\(v_{i}\) 是每一列的MEX
矩阵价值为MEX(\(v_{1}\), \(v_{2}\), \(v_{3}\) ....), 输出最大价值的矩阵
思路:
要想价值最大,那最理想的情况就是每一列的 MEX = [0, 1, ... , m - 1], 这样矩阵价值就是m
比如当 m = 4 时这样的矩阵为:
[1, 2, 3, 0]
[2, 3, 0, 1]
[3, 0, 1, 2]
就是把[0, m - 1]不断循环左移,这样的话 n = m - 1;
那 n < m - 1 怎么办?
其实就是在上面的情况下删掉一些行,那么MEX = [0, 1, ... , m - 1]就会少几个,那最大就是 n + 1;
那 n > m - 1 怎么办?
其实只需要一直重复第一行就行了,这样就不会改变MEX
inline void solve()
{
int n, m; cin >> n >> m;
if (m == 1)
{
cout << '0' << endl;
for (int i = 1; i <= n; i++)
cout << 0 << endl;
return;
}
else cout << min(n + 1, m) << endl;
int idx = 1;
std::vector<int> a;
for (int i = 0; i < m; i++)
a.pb(i);
for (int i = 1; i <= n; i++)
{
if (i > m - 1)
{
idx = 1;
cout << a[idx] << ' ';
for (int j = (idx + 1) % m; j != idx; j = (j + 1) % m)
cout << a[j] << ' ';
cout << endl;
continue;
}
cout << a[idx] << ' ';
for (int j = (idx + 1) % m; j != idx; j = (j + 1) % m)
cout << a[j] << ' ';
cout << endl;
idx = (idx + 1) % m;
}
}
D1
题意:
n个人每个人都有a[i]个糖果,每个人都需要别人\(2^{x}\)个糖果,并收到别人给的\(2^{y}\)糖果, 问最后能不能让每个人的糖果一样多
思路:
很容易想到每个人最后的糖果个数一定是平均值ave, 那么|a[i] - ave| = \(2^{y}\) - \(2^{x}\) 一定是2的幂次,并且所有人给出去的糖果和收到的糖果一定相等
inline void solve()
{
int n; cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
LL s = accumulate(a.begin(), a.end(), LL(0));
if (s % n)
{
cout << "NO" << endl;
return;
}
LL ave = s / n;
std::vector<int> cnt(31, 0);
for (int i = 0; i < n; i++)
{
if (a[i] < ave)
{
int d = ave - a[i];
int l = __builtin_ctz(d);
cnt[l]++;
d += 1 << l;
if (d & (d - 1))
{
cout << "NO" << endl;
return;
}
cnt[__builtin_ctz(d)]--;
}
else if (a[i] > ave)
{
int d = a[i] - ave;
int l = __builtin_ctz(d);
cnt[l]--;
d += 1 << l;
if (d & (d - 1))
{
cout << "NO" << endl;
return;
}
cnt[__builtin_ctz(d)]++;
}
}
for (int i = 0; i < 31; i++)
if (cnt[i])
{
cout << "NO" << endl;
return;
}
cout << "YES" << endl;
}

浙公网安备 33010602011771号