题目链接
(A. Minimal Square)
(Description:)
将两个相同得矩形放在一个正方形中,求正方形的最小面积。
(Solution:)
取得矩形的长和宽,显然只有两个矩形横着放最优。
(Code:)
/*
@Author: nonameless
@Date: 2020-05-25 08:29:45
@Email: 2835391726@qq.com
@Blog: https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
int main(){
int t; cin >> t;
while(t --){
int a, b; cin >> a >> b;
if(a < b) swap(a, b);
int e = max(a, b + b);
cout << e * e << endl;
}
return 0;
}
(B. Honest Coach)
(Description:)
将 (n) 个数分为两组,要求一组的最大值减去另一组的最小值的绝对值最小。
(Solution:)
排序后,在相邻两个数之间取差。
(Code:)
/*
@Author: nonameless
@Date: 2020-05-25 08:38:29
@Email: 2835391726@qq.com
@Blog: https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
const int N = 55;
int s[N];
int main(){
int t; cin >> t;
while(t --){
int n; cin >> n;
for(int i = 1; i <= n; i ++) scanf("%d", &s[i]);
sort(s + 1, s + n + 1);
int ans = INF;
for(int i = 2; i <= n; i ++) ans = min(ans, s[i] - s[i - 1]);
cout << ans << endl;
}
return 0;
}
(C. Similar Pairs)
(Description:)
给出 (n) 个数,要求两个进行配对,要求是 (a_i, a_j) 同奇偶或者 (|a_i - a_j| = 1)。问这 (n) 个数能否完成配对?
(Solution:)
由于 (n) 是偶数,那么当数列中奇数的个数为偶数时,偶数的个数也为偶数,显然这种情况下是一定可以的,那么当数列中奇数的个数为奇数时,我们只需要找到一组 (|a_i - a_j| = 1) 即可,由于 (a_i, a_j) 一定是一个是奇数,一个是偶数的,那么减去这一组之后,奇数的个数和偶数的个数都变为了偶数,回到了第一中情况。
(Code:)
/*
@Author: nonameless
@Date: 2020-05-25 08:42:55
@Email: 2835391726@qq.com
@Blog: https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
const int N = 55;
int a[N];
int main(){
int t; cin >> t;
while(t --){
int n; cin >> n;
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
sort(a + 1, a + n + 1);
int mark = 0;
int cntOdd = 0;
for(int i = 1; i <= n; i ++){
if(a[i] & 1) cntOdd ++;
if(i < n && a[i] + 1 == a[i + 1]) mark = 1;
}
if(mark || cntOdd % 2 == 0) puts("YES");
else puts("NO");
}
return 0;
}
(D. Buying Shovels)
(Description:)
给你 (n) 和 (k),要求在 ([1, k]) 中找到一个数 (x),使得 (n mod x = 0),并且 (frac{n}{x}) 最小。
(Solution:)
找到 ([1, k]) 中 (n) 最大的约数即可。
(Code:)
/*
@Author: nonameless
@Date: 2020-05-25 09:03:23
@Email: 2835391726@qq.com
@Blog: https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
int cal(int n, int k){
int res = 1;
for(int i = 2; i * i <= n; i ++){
if(n % i == 0){
if(i <= k) res = max(res, i);
if(n / i <= k) res = max(res, n / i);
}
}
return res;
}
int main(){
int t; cin >> t;
while(t --){
int n, k; cin >> n >> k;
if(k >= n) puts("1");
else{
int ans = cal(n, k);
cout << n / ans << endl;
}
}
return 0;
}
(E. Polygon)
(Description:)
矩阵的最上边和最左边有一排大炮,可以无限制的打出一个 (1), (1) 遇到 (1) 或矩阵的边界就停下,并且他停下的那一格变为了 (1),具体可以看原题的图.给出打完后的矩阵,问是否是合法的?
(Solution:)
我们直接去暴力,看每一个 (1) 的右边和下边一格是否是 (1) 或边界,有一个不满足就是不合法的。
(Code:)
/*
@Author: nonameless
@Date: 2020-05-25 09:22:27
@Email: 2835391726@qq.com
@Blog: https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
const int N = 55;
char s[N][N];
int main(){
int t; cin >> t;
while(t --){
int n; cin >> n;
for(int i = 1; i <= n; i ++) scanf("%s", s[i] + 1);
int mark = 1;
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n; j ++){
if(s[i][j] == '1'){
if(i != n && j != n && s[i + 1][j] == '0' && s[i][j + 1] == '0'){
mark = 0;
break;
}
}
}
if(mark == 0) break;
}
if(mark) puts("YES");
else puts("NO");
}
return 0;
}
(F. Spy-string)
(Description:)
给出 (n) 个字符串,问是否存在一个基串去与这 (n) 个字符串比较,最多只有一个位置的字符不一样?
(Solution:)
还是暴力,我们直接以第一个字符串为基串,然后去改变他每个位置上的字符(每次只能改变一个位置),来和其他的比较,看是否合法。
(Code:)
/*
@Author: nonameless
@Date: 2020-05-25 09:32:49
@Email: 2835391726@qq.com
@Blog: https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
const int N = 15;
int n, m;
char s[N][N];
int chk(char *t){
for(int i = 2; i <= n; i ++){
int cnt = 0;
for(int j = 1; j <= m; j ++){
if(s[i][j] != t[j]) cnt ++;
}
if(cnt > 1) return 0;
}
return 1;
}
int main(){
int t; cin >> t;
while(t --){
cin >> n >> m;
for(int i = 1; i <= n; i ++) scanf("%s", s[i] + 1);
char t[N];
for(int i = 1; i <= m; i ++) t[i] = s[1][i];
int flag = 0;
for(int i = 1; i <= m; i ++){
for(char j = 'a'; j <= 'z'; j ++){
t[i] = j;
if(chk(t)){
flag = 1;
break;
}
}
if(flag) break;
t[i] = s[1][i];
}
t[m + 1] = ' ';
if(flag) printf("%s
", t + 1);
else puts("-1");
}
return 0;
}
(G. A/B Matrix)
(Description:)
问是否存在一个 (n imes m) 的矩阵,使得每一行有 (a) 个 (1),每一列有 (b) 个 (1) ?
(Solution:)
先根据行来构造,但每一行应该怎么放呢?为了尽可能的合理,每一列我们都应该照顾到,所以我们顺序的摆放过去。
(Code:)
/*
@Author: nonameless
@Date: 2020-05-25 16:57:59
@Email: 2835391726@qq.com
@Blog: https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
const int N = 55;
int n, m, a, b;
int mt[N][N];
int chk(){ // 判断构造完是否合法
for(int j = 0; j < m; j ++){
int cnt = 0;
for(int i = 0; i < n; i ++)
cnt += mt[i][j];
if(cnt != b) return 0;
}
return 1;
}
int main(){
int t; cin >> t;
while(t--){
cin >> n >> m >> a >> b;
memset(mt, 0, sizeof mt);
int idx = 0; // 从 0 开始
for(int i = 0; i < n; i ++){
for(int j = idx; j < idx + a; j ++){ // 顺序构造,注意模 m
mt[i][j % m] = 1;
}
idx += a;
}
if(!chk()) puts("NO");
else{
puts("YES");
for(int i = 0; i < n; i ++){
for(int j = 0; j < m; j ++)
printf("%d", mt[i][j]);
puts("");
}
}
}
return 0;
}
(H. Binary Median)
(Description:)
有 (2^m) 个长度为 (m) 的 (01) 字符串,在去掉 (n) 个字符串后,对剩余的字符串排序,问下标为中位数的那个字符串是什么?
(Solution:)
先把字符串转为十进制,然后我们不要一下删除掉 (n) 个数,而是一个一个的删掉,对于删去一个数之后,中位数就有可能发生变化,在手动模拟几遍之后就可以发现规律:
当前数的个数为偶数,如果要删去的数要 (leq) 中位数,那么中位数向右移一位;
当前数的个数为奇数,如果要删去的数要 (geq) 中位数,那么中位数向左移一位。
(Code:)
/*
@Author: nonameless
@Date: 2020-05-25 20:58:38
@Email: 2835391726@qq.com
@Blog: https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
int main(){
int t; cin >> t;
while(t --){
int n, m;
cin >> n >> m;
map<ll, int> mp;
vector<ll> vec;
for(int i = 1; i <= n; i ++){
string s; cin >> s;
ll t = 0;
for(int j = 0; j < m; j ++) t = t * 2 + s[j] - '0';
//cout << "t = " << t << endl;
vec.pb(t);
}
ll k = 1ll << m;
ll ans = (k - 1) / 2;
for(int i = 0; i < n; i ++){
mp[vec[i]] = 1;
if(k % 2 == 0){
if(vec[i] <= ans){
ans ++;
while(mp[ans]) ans ++;
}
}else{
if(vec[i] >= ans){
ans --;
while(mp[ans]) ans --;
}
}
k --; // 由于删去了一个数,所以个数 -1
// cout << "ans = " << ans << endl;
}
string s = "";
for(int i = 0; i < m; i ++){
if(ans >> i & 1) s += '1';
else s += '0';
}
reverse(all(s));
cout << s << endl;
}
return 0;
}