[每日一题2020.06.10]Codeforces Round #644 (Div. 3) ABCDEFG
花了5个多少小时总算把div3打通一次(
problem A
题意 : 两个x*y的矩形不能重叠摆放, 要放进一个正方形正方形边长最小为多少
先求n = min(2x, 2y, x+y)
再求max(n, x, y)即为正方形边长
/*
* Author: RoccoShi
* Time: 2020-06-10 20:05:02
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
int x, y;
cin >> x >> y;
int minn = min(x+x, y+y);
minn = min(minn, x+y);
int ans = max(minn, x);
cout << pow(max(ans, y),2) << endl;
}
return 0;
}
problem B
题意 : 找一个数组排序后相邻最小的两个数
排序后扫一遍
/*
* Author: RoccoShi
* Time: 2020-06-10 20:05:02
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int team[55];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int minn = 9999;
for (int i = 0; i < n; ++i)
{
cin >> team[i];
}
sort(team, team + n);
for (int i = 1; i < n; ++i)
{
if (minn > team[i]-team[i-1]) {
minn = team[i]-team[i-1];
}
}
cout << minn <<endl;
}
return 0;
}
problemC
题意 :
规则1 : 两个奇数或者两个偶数可以组一个team
规则2 : 相差为1的两个数可以组一个team
问 : 所有编号能否全部组成team
分别统计奇数和偶数的个数, 相差为1的两个数必为奇数和偶数
奇数和偶数的个数有两种情况 :
- 均为奇数
- 均为偶数
第二种必可以, 第一种只要有一对以上的规则2就可以变为第二种
/*
* Author: RoccoShi
* Time: 2020-06-10 20:05:02
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[55];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int cntodd = 0, cnteven = 0, cntpair = 0;
for (int i = 0; i < n; ++i) {
cin >> a[i];
if (a[i] % 2 == 1)
cntodd++;
else
cnteven++;
}
sort(a, a+n);
for (int i = 1; i < n; ++i)
{
if(a[i]-a[i-1]==1){
cntpair++;
i++;
}
}
if(cnteven % 2 == 1 && cntodd % 2 ==1 ) {
if(!cntpair)
cout << "NO" <<endl;
else
cout << "YES" << endl;
}
else
cout<< "YES" <<endl;
}
return 0;
}
problem D
题意 :
找一个数n的所有因数里小于等于k的最大值
这题想了好久啊....
首先, 找一个数的因数 不用! 遍历! 所有! 数!
只需要把i从1遍历到\(\sqrt{n}\) 就可以了!
如果n可以整除i, 那么因数有两个, 一个是n/i, 还有一个是i
比如8, 我们遍历1,2就可以得到因数 1, 2, 4, 8
接下来只需要判断这个数是否<=k即可
如果k大于等于n, 直接输出1就可以了
/*
* Author: RoccoShi
* Time: 2020-06-10 20:05:02
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
int n, k;
cin >> n >> k;
if ( k >= n) {
cout << 1 << endl;
}
else
{
int m = sqrt(n);
int ans = n;
for (int i = m; i >= 1; --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;
}
problem E
题意 : 俄罗斯方块类, n*n的正方形上面和左边各有n个发射口, 发射顺序自定义, 1为该处有个块, 0为没有. 问是否能堆叠成给定的形状
扫描一波判断所有的1下面或者右边是否有个0, 如果都莫得直接输出NO
/*
* Author: RoccoShi
* Time: 2020-06-10 20:05:02
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int x[55][55];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
bool flag = 1;
char s;
cin.get();
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
s = cin.get();
//cout.put(s);
x[i][j] = s=='0'?0:1;
}
s=cin.get();
//cout.put(s);
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if(i == n-1 || j == n-1)
continue;
else if(x[i][j] == 1)
{
if((x[i][j+1] || x[i+1][j]) == 0)
flag = 0;
}
}
}
if(flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
problem F
题意 : 给n个字符串问是否存在一个字符串与每个字符串都只有一个地方不同
给定范围很小, 考虑直接暴力, 最大遍历不过为\(10 \times 10 \times 26\)
直接把字符串存起, 然后遍历判断
/*
* Author: RoccoShi
* Time: 2020-06-10 20:05:02
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<string> s(15);
string x(15, '\0');
int m, n;
bool is1(){
for (int i = 0; i < n; ++i)
{
int cnt = 0;
for (int j = 0; j < m; ++j)
{
cnt += (x[j] == s[i][j] ? 0 : 1 );
}
if(cnt > 1)
return false;
}
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--) {
bool flag = false;
cin >> n >> m;
for (int i = 0; i < n; ++i)
cin >> s[i];
for (int i = 0; i < m; ++i)
{
x[i] = s[0][i];
}
for (int i = 0; i < m; ++i)
{
for (int j = 'a'; j <= 'z'; ++j) {
x[i] = j;
if(is1()){
flag = true;
break;
}
}
if(flag)
break;
x[i] = s[0][i];
}
if(flag == 1) {
for (int i = 0; i < m; ++i)
{
cout<< x[i];
}
cout << endl;
}
else
cout << "-1" << endl;
}
return 0;
}
problem G
题意 : 给定n*m的矩阵和数字a, b. 问是否存在每行有a个1且每列有b个1的排列
首先判断是否\(n \times a = b \times m\) , 如果是那么必存在这样的排列
怎么排? 循环排列即可
比如n = 4, m = 6, a = 3, b = 2
就
111000
000111
111000
000111
/*
* Author: RoccoShi
* Time: 2020-06-10 20:05:02
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 55;
int mp[maxn][maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
int n, a, m, b;
while(t--) {
cin >> n >> m >> a >> b;
if(n*a != m*b)
{
cout << "NO" << endl;
}
else
{
cout << "YES" << endl;
int pos = 0;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < a; ++j)
{
mp[i][pos++] = 1;
pos %= m;
}
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j) {
cout << mp[i][j];
mp[i][j] = 0;
}
cout << endl;
}
}
}
return 0;
}