Codeforces Round #644 (Div. 3)(2020.5.27)
今日新闻:零基础大哥经过半年ACM学习已经超过了大三学长,昨天一把Div2打上紫名。
我这个蒟蒻何时才能出头…
A、Minimal Square
这题只有两个矩形,所以肯定要么竖着并起来放要么横着并起来放,取个最小值就好了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int t; cin >> t;
while (t--)
{
int a, b; cin >> a >> b;
ll ans = min(max(2 * a, b), max(a, 2 * b));
cout << ans * ans << endl;
}
return 0;
}
B、Honest Coach
排个序,然后找相邻元素差最小的那个输出即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int main()
{
int t; cin >> t;
while (t--)
{
int n; cin >> n;
vector <int> a;
for (int i = 1; i <= n; ++i)
{
int x; cin >> x;
a.push_back(x);
sort(a.begin(), a.end());
}
int ans = INF;
for (int i = 1; i < a.size(); ++i)
ans = min(ans, a[i] - a[i - 1]);
cout << ans << endl;
}
return 0;
}
C、Similar Pairs
乍一看有些无从下手。
可以先统计一下奇偶性,如果都是偶数个那就可以两两配对。又因为题目给了 是偶数,所以一个是奇数那另一个也必定是奇数,这时候可以取一奇一偶之后剩下的配对,然后我们就找一下有没有相差为1的数就可以了。因为相差为1时奇偶性必定不同。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int t; cin >> t;
while (t--)
{
int n; cin >> n;
vector <int> a;
int par[2] = {0};
for (int i = 1; i <= n; ++i)
{
int x; cin >> x;
a.push_back(x);
par[x % 2]++;
}
if (par[0] % 2)
{
sort(a.begin(), a.end());
for (int i = 1; i < a.size(); ++i)
if (a[i] - a[i - 1] == 1)
{
cout << "YES" << endl;
goto OUT_LOOP;
}
cout << "NO" << endl;
}
else cout << "YES" << endl;
OUT_LOOP:;
}
return 0;
}
D、Buying Shovels
枚举最小袋数 ,看 是否小于 。
不过这样做还要当心枚举的 一个都不满足 小于 的情况,此时并不一定 就是最小值,所以可以在两种满足条件的情况中取个最小。
具体见代码。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int main()
{
int t; cin >> t;
while (t--)
{
ll n, k; cin >> n >> k;
ll ans = INF;
for (ll i = 1; i * i <= n; ++i)
{
if (n % i == 0)
{
if (i <= k) ans = min(ans, n / i);
if (n / i <= k) ans = min(ans, i);
}
}
cout << ans << endl;
}
return 0;
}
E、Polygon
做题的时候看tag居然看到了什么最短路这种东西,吓死我了。
结果做完之后感觉这tag误导性真的很大。
先给判断条件:遍历整张图,对于1来说右边或者下面至少要有一个地方有1。
下面给出正确性证明:可以考虑一个类似于归纳法的东西。
最右边和最下面是边界,那么我们考虑与边界相邻的格子,这堆格子的任意一个01排列都是可以用某种顺序开炮得到的。
然后得到某个排列之后我们就可以把和边界相邻的格子删掉了,因为此时这些格子对答案没有影响。于是可以继续重复上述操作到所有格子全被删完为止。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 80;
int main()
{
int t; cin >> t;
while (t--)
{
int n; cin >> n;
char mp[MAXN][MAXN];
for (int i = 1; i <= n; ++i)
cin >> mp[i] + 1;
for (int i = 1; i <= n + 1; ++i) mp[n + 1][i] = '1';
for (int i = 1; i <= n + 1; ++i) mp[i][n + 1] = '1';
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (mp[i][j] == '1')
{
if (mp[i][j + 1] == '1' || mp[i + 1][j] == '1') continue;
else
{
cout << "NO" << endl;
goto OUT_LOOP;
}
}
cout << "YES" << endl;
OUT_LOOP:;
}
return 0;
}
F、Spy-string
这种题果然是我的克星。
想了半天没想到什么好方法,看题解。
居然就是暴力中的暴力枚举哪一位修改,修改成什么。
好吧。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 50;
string a[MAXN];
bool check(int n, int k, string ans)
{
for (int i = 1; i <= n; ++i)
{
int cnt = 0;
for (int j = 0; j < k; ++j)
if (ans[j] != a[i][j]) ++cnt;
if (cnt > 1) return 0;
}
return 1;
}
int main()
{
int t; cin >> t;
while (t--)
{
int n, k; cin >> n >> k;
for (int i = 1; i <= n; ++i) cin >> a[i];
if (check(n, k, a[1])) cout << a[1] << endl;
else
{
for (int i = 0; i < k; ++i)
{
map <char, int, less<int>> mp;
for (int j = 1; j <= n; ++j) mp[a[j][i]]++;
for (auto &j : mp)
{
string ans = a[1];
ans[i] = j.first;
if (check(n, k, ans))
{
cout << ans << endl;
goto NEXT;
}
}
}
cout << -1 << endl;
}
NEXT:;
}
return 0;
}
G、A/B Matrix
这题不太会构造,搞了半天还是错的。
于是请教队友,队友凭直觉一秒搞了个构造方法然后AC了…
我:???
首先存在与否的条件肯定是 ,这没啥问题。
之后构造,队友说就从左往右构造。比如第一行就是第一个到第 个元素全是1,之后的行在之前行的基础上继续往后写,第二行就从 个元素开始写 个1,如果跑到矩阵外面就回到第一个元素接着写。
不过我直接懵了。这为啥是对的?
后来简单想了一下发现真是对的。把这堆1排成一列,因为是按行写的所以个数肯定是 个。又由给出的存在条件,发现 ,因此 也是 的倍数,所以对于列来说1的位置就是个剩余系,肯定完全包含在里面了而且个数相等…
菜是原罪。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100;
int main()
{
int t; cin >> t;
while (t--)
{
int n, m, a, b; cin >> n >> m >> a >> b;
if (n * a != m * b)
{
cout << "NO" << endl;
continue;
}
else
{
cout << "YES" << endl;
bool matrix[MAXN][MAXN] ={0};
int col = 1;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= a; ++j)
{
matrix[i][col++] = 1;
if (col > m) col =1;
}
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
cout << matrix[i][j];
cout << endl;
}
}
}
return 0;
}