A. Minimal Square
题意:两个相等的矩形,长宽为a,b求一个最小的正方形,能够不重叠地放下这两个矩形。
思路:要么都横着放,要么都竖着放,要么一横一竖。取最小。
AC代码:
#include <bits/stdc++.h>
#define int long long
#define mk make_pair
#define PII pair<int,int>
const int N = 1e6+10;
const int mod = 1e9+7;
using namespace std;
int n,m;
int res =0 ;
int k,q;
int cnt[N];
int a[N];
int b[N];
int mark[N];
int mark2[N];
signed main(){
int t = 1;
cin>>t;
while(t--){
int a,b;
cin>>a>>b;
int res = a+b;
res = min(res,max(2*a,b));
res = min(res,max(a,2*b));
cout<<res*res<<endl;
}
return 0;
}
B. Honest Coach
题意:给定一个数组,分成两部分,且不为空,求 第一部分的最大值和第二部分的最小值的差值 的最小值。
思路:显然,排个序之后,求相邻两数的最小差值,就是解。
AC代码:
#include <bits/stdc++.h>
#define int long long
#define mk make_pair
#define PII pair<int,int>
const int N = 1e6+10;
const int mod = 1e9+7;
using namespace std;
int n,m;
int res =0 ;
int k,q;
int cnt[N];
int a[N];
int b[N];
int mark[N];
int mark2[N];
signed main(){
int t = 1;
cin>>t;
while(t--){
cin>>n;
for(int i = 0 ; i < n ; i ++) cin>>a[i];
sort(a,a+n);
int res = a[n-1]-a[0];
for(int i = 1 ; i < n ; i ++){
res = min(a[i]-a[i-1],res);
}
cout<<res<<endl;
}
return 0;
}
C. Similar Pairs
题意:给定一个数组,定义 奇偶性相同的 或者 绝对值相差1 的数为同类的数。问能否把n个数分成n/2组同类的数。
思路:显然,求出奇偶的个数,对于定义的第二种情况,如果选了两个数,那么奇偶个数各减1。因为n是偶数,当奇数个数为偶数时,偶数个数也是偶数,反之同理。那么只有当奇数个数为奇数时,只要用定义2拿走一组数,就都变成偶数了。那就可以两两分组了!
AC代码:
#include <bits/stdc++.h>
#define int long long
#define mk make_pair
#define PII pair<int,int>
const int N = 1e6+10;
const int mod = 1e9+7;
using namespace std;
int n,m;
int res =0 ;
int k,q;
int cnt[N];
int a[N];
int b[N];
int mark[N];
int mark2[N];
signed main(){
int t = 1;
cin>>t;
while(t--){
cin>>n;
for(int i = 0 ; i < n ; i ++) cin>>a[i];
sort(a,a+n);
int cnt = 0;
for(int i = 0 ; i < n ; i ++) cnt += a[i]%2;
int cnt2 = 0;
int cnt1 = n-cnt;
for(int i = 1 ; i < n ; i ++){
if(a[i]-a[i-1] == 1){
cnt2++; i ++;
}
}
if(cnt%2 == 0 || cnt2 >0){
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
}
return 0;
}
D. Buying Shovels
题意:去商店买东西,总共要买n件(不能多不能少),但是商店只能一捆一捆得卖(捆绑销售)。每一捆分别装有 1-k 件商品。现在只能选某一捆买,每个不同的捆 数量是无限多的。问最少需要买几捆。
思路:显然,是要找不大于k的,最大的n的约数x。答案就是 n/x。
AC代码:
#include <bits/stdc++.h>
#define int long long
#define mk make_pair
#define PII pair<int,int>
const int N = 1e6+10;
const int mod = 1e9+7;
using namespace std;
int n,m;
int res =0 ;
int k,q;
int cnt[N];
int a[N];
int b[N];
int mark[N];
int mark2[N];
signed main(){
int t = 1;
cin>>t;
while(t--){
int x,y;
cin>>x>>y;
if(y >= x){
cout<<1<<endl;
}else{
int res = x;
for(int i = 1 ; i*i <= x && i <= y; i ++){
if(x%i == 0){
res = min(res,x/i);
if(x/i <= y)
res = min(res,x/(x/i));
}
}
cout<<res<<endl;
}
}
return 0;
}
E. Polygon
题意:这样的子的炮阵,每个炮可以向前开炮,炮弹会在碰到墙时或者碰到别的炮时停下来,并停留在那里。现在给出一个01矩阵,1表示炮弹,问是否是能通过合理的开炮顺序,形成这样的矩阵。
思路:显然,左边的炮发射出去会一路向东(右),上面的炮发射出去会一路向南(下),直到碰到障碍物。那么显然,每一个停下来的炮弹,要么被右边挡住了去路,要么被下边挡住了去路,如果一个炮弹两边都没挡住却停留在了那里,那就是不合法的。只需要判断这个就行。
AC代码:
#include <bits/stdc++.h>
#define int long long
#define mk make_pair
#define PII pair<int,int>
const int N = 1e6+10;
const int mod = 1e9+7;
using namespace std;
int n,m;
int res =0 ;
int k,q;
int cnt[N];
int a[N];
int b[N];
int mark[N];
int mark2[N];
string s[1005];
signed main(){
int t = 1;
cin>>t;
while(t--){
cin>>n;
for(int i = 0 ; i < n ; i ++) cin>>s[i];
int flag = 1;
for(int i = 0 ; i < n ; i ++){
for(int j = 0 ; j <n ; j ++){
if(s[i][j] == '1'){
if((i+1 >= n || s[i+1][j] == '1') || (j+1 >= n || s[i][j+1] == '1')){
}else{
flag = 0;
break;
}
}
}
if(!flag) break;
}
puts(flag ? "YES" : "NO");
}
return 0;
}
F. Spy-string
题意:给定n个长度为m的字符串,让找出一个字符串使得和任意一个字符串只有最多一个不同的字符。没有则输出-1
思路:刚开始想了一会,有没有啥规律,想了半天没想出来,作罢。写了一手暴力dfs。适当的剪枝一下就行了。
AC代码:
#include <bits/stdc++.h>
#define int long long
#define mk make_pair
#define PII pair<int,int>
const int N = 1e6+10;
const int mod = 1e9+7;
using namespace std;
int n,m;
int res =0 ;
int k,q;
int cnt[N];
int a[N];
int b[N];
int mark[N];
int mark2[N];
string s[1005];
char ans[10005];
int flag;
bool check(int pos){
for(int i = 0 ; i < n ; i ++){
int cnt = 0;
for(int j = 0 ; j <= pos ; j ++){
if(s[i][j] != ans[j]) cnt++;
if(cnt > 1) return false;
}
}
return true;
}
void dfs(int pos){
if(flag) return;
if(pos == m){
flag = 1;
return;
}
for(int i = 0 ; i < 26 ; i ++){
ans[pos] = ('a'+i);
if(check(pos)){
dfs(pos+1);
}
if(flag) return;
}
}
signed main(){
int t = 1;
cin>>t;
while(t--){
cin>>n>>m;
for(int i = 0 ; i < n ; i ++) cin>>s[i];
flag = 0;
dfs(0);
if(flag){
for(int i = 0 ; i < m ; i ++){
cout<<ans[i];
}
cout<<endl;
}else{
cout<<-1<<endl;
}
}
return 0;
}
G. A/B Matrix
题意:问能不能找到一种每行有a个1,每列有b个1,的大小为n*m的矩阵。
思路:首先判断不合法的条件,合法的条件就是n*b == m*a,至少要保证1的个数一致嘛,不然不就相互矛盾了。然后开始填矩阵,就从(0,0)位置开始按行填连续的1,第一行填a个1,第二行就不要从头开始填,从上次结束的位置的下一个位置,开始填。这样的做的目的呢,就相等于,用n*a个1 去均匀得覆盖 m列,那么显然每一列上就会有 (n*a)/m个1,因为n*b == m*a 所以正好是满足条件的。
AC代码:
#include <bits/stdc++.h>
#define int long long
#define mk make_pair
#define PII pair<int,int>
const int N = 1e6+10;
const int mod = 1e9+7;
using namespace std;
int n,m;
int k,q;
int a,b;
int res[100][100];
void show(){
for(int i = 0 ; i < n ; i ++){
for(int j = 0 ; j < m ; j ++){
cout<<res[i][j];
}
cout<<endl;
}
}
signed main(){
int t = 1;
cin>>t;
while(t--){
cin>>n>>m>>a>>b;
if(b*m != a*n){
cout<<"NO"<<endl;
}else{
cout<<"YES"<<endl;
int flag = 0;
int pre = 0;
for(int i = 0 ; i < n ; i ++){
int tmp = 0;
int tt = 0;
for(int j = 0 ; j < m ; j ++){
if(tmp < a){
res[i][pre] = 1;
pre = (pre+1)%m;
tmp ++;
}else{
res[i][(pre+tt++)%m] = 0;
}
}
}
show();
}
}
return 0;
}
H. Binary Median
题意:给出n个二进制数和一个m。表示从[0,2m-1] 中删除这些数。然后求剩下的中位数。
思路:如果没有删除数,那么答案显然是 mid = (2m-1)/2,现在假设删除都是mid 右边的数。也就是 mid = (2m-n-1)/2。但是显然假设不成立。可能也会删mid左边的数。所以如果a[i] < mid,mid就要往右移动一格,也就是 mid += 1 。所以对a排个序就好了。
AC代码:
#include <iostream>
#include <bits/stdc++.h>
#define int long long
#define mk make_pair
#define gcd __gcd
using namespace std;
const double eps = 1e-10;
const int mod = 1e9+7;
const int N = 3e3+7;
int n,m,k,t = 1,cas = 1;
int a[N],b[N];
signed main(){
cin>>t;
while(t--){
cin>>n>>m;
for(int i = 0 ; i < n ; i ++){
string s;cin>>s;
a[i] = 0;
for(int j = 0 ; j < m ; j ++){
a[i] = (a[i]<<1)+s[j]-'0';
}
}
sort(a,a+n);
int mid = ((1LL<<m)-n-1)>>1;
for(int i = 0; i < n ; i ++){
if(a[i] <= mid) mid ++;
}
char s[200];
for(int i = 0 ; i < m ; i ++){
s[i] = '0'+(mid&1);
mid >>= 1;
}
for(int i = m-1 ; i >= 0 ; i --){
cout<<s[i];
}
cout<<endl;
}
}