Codeforces Round #644 (Div. 3)题解

题目链接

A. Minimal Square

题意:
ab给一个长宽分别为a,b的矩形
问两个矩形放在一个正方形内,正方形的面积最小为多少
题解:
分别看矩形的长和宽拼到一起的情况
a,2b长拼到一起的边为a,2*b
b,2a宽拼到一起的边为b,2*a
同种情况内取最大边,然后这两种情况取最小
AC代码

/*
    Author:zzugzx
    Lang:C++
    Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=2e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};


int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int _;
    cin>>_;
    while(_--){
        int a,b;
        cin>>a>>b;
        int s=max(a,2*b);
        int s1=max(b,2*a);
        int ans=min(s,s1);
        cout<<ans*ans<<endl;
    }
    return 0;
}


B. Honest Coach

题意:
n一个长度为n数组,分成两个数列
使使得一个数列的最大值和另一个数列的最小值差最小
求出最小值
题解:
ii+1n直接数组排序,前i个一组,i+1到n一组
用第二组的最小值减第一组的最大值就是结果
所以直接排序后求相邻数的差
AC代码

/*
    Author:zzugzx
    Lang:C++
    Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

int a[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int _;
    cin>>_;
    while(_--){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        sort(a+1,a+1+n);
        int ans=inf;
        for(int i=2;i<=n;i++){
            ans=min(ans,a[i]-a[i-1]);
        }
        cout<<ans<<endl;
    }
    return 0;
}


C. Similar Pairs

题意:
1如果两个数奇偶性相同,或者差为1,则可以组成一对
nn使给n个数(n为偶数),问能否使得每个数都配对
题解:
n由于n为偶数,那么奇数个数和偶数个数奇偶性相同
如果都为偶,直接各自配对即可
1如果为奇,看是否都有一对奇数和偶数相差为1配对
NO如果找不到就NO
AC代码

/*
    Author:zzugzx
    Lang:C++
    Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

int a[110],cnt[110];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int _;
    cin>>_;
    while(_--){
        memset(cnt,0,sizeof cnt);
        int n;
        cin>>n;
        int x=0,y=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            cnt[a[i]]++;
            if(a[i]&1)x++;
            else y++;
        }
        bool f=0;
        for(int i=1;i<=n;i++)
            if(cnt[a[i]+1]||cnt[a[i]-1]){f=1;break;}
        if(!f&&(x&1))cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
    return 0;
}


D. Buying Shovels

题意:
n给你一个数n
1k使ppn找一个1-k的数,使得这个数乘p(p为整数)为n
p求最小p
题解:
nx1k直接枚举n的所有因子x,如果这个因子在1-k
n/x那么计算一下n/x,并取最小值
AC代码

/*
    Author:zzugzx
    Lang:C++
    Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};


int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int _;
    cin>>_;
    while(_--){
        int n,k;
        cin>>n>>k;
        int ans=inf;
        for(int i=1;i*i<=n;i++){
            int t=n/i;
            if(n%i==0&&i<=k)ans=min(ans,n/i);
            if(n%t==0&&t<=k)ans=min(ans,n/t);
        }
        cout<<ans<<endl;
    }
    return 0;
}


E. Polygon

题意:
每行左侧和每列上侧有一个炮台
每一时刻可以有一个炮台发出炮弹
炮弹碰到墙壁或者另一个炮弹会停下来并留在原地
问给出的图是否合法
题意:
由于每行左侧和每列上侧有炮台
一个位置想要有炮弹,必须保证他是边界
使或者他的下面或右边有一个炮弹使他停止,枚举判断即可
AC代码

/*
    Author:zzugzx
    Lang:C++
    Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

char g[100][100];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int _;
    cin>>_;
    while(_--){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)cin>>g[i]+1;
        bool f=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(g[i][j]=='1'){
                    if(i==n||j==n)continue;
                    if(g[i][j+1]=='0'&&g[i+1][j]=='0'){f=1;break;}
                }
            }
            if(f)break;
        }
        if(f)cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
    return 0;
}


F. Spy-string

题意:
nm给出n个字符串,长度都为m
是否能找到一个字符串
n这个字符串和这n个字符串的每一个最多只有一个不同的字符
题解:
DFS直接DFS暴力枚举每一个字符
搜索的同时用二进制记录一个状态
i记录第i个字符串能否再出现不同字符
1如果为1则能,否则不能
100return如果出现且对应状态为1,置0,如果对应状态为0直接进行return
return然后每次进行回溯,记录当前字符串,找到后return输出
AC代码

/*
    Author:zzugzx
    Lang:C++
    Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

bool f;
int n,m,cnt[26];
vector<char> v[20];
char ans[20];
string s[20];
void dfs(int cur){
    if(f)return;
    for(int i=1;i<=n;i++)if(cnt[i]>1)return;
    if(cur==m){
        for(int i=0;i<m;i++)cout<<ans[i];
        cout<<endl;
        f=1;return;
    }
    for(auto i:v[cur]){
        for(int j=1;j<=n;j++)if(s[j][cur]!=i)cnt[j]++;
        ans[cur]=i;
        dfs(cur+1);if(f)return;
        for(int j=1;j<=n;j++)if(s[j][cur]!=i)cnt[j]--;
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int _;
    cin>>_;
    while(_--){
        cin>>n>>m;
        for(int i=1;i<=n;i++)cin>>s[i];
        f=0;
        for(int i=0;i<m;i++){
            v[i].clear();
            memset(cnt,0,sizeof cnt);
            for(int j=1;j<=n;j++)
                cnt[s[j][i]-'a']++;
            for(int j=0;j<26;j++)
                if(cnt[j])v[i].pb(j+'a');
        }
        memset(cnt,0,sizeof cnt);
        dfs(0);if(!f)cout<<-1<<endl;
    }
    return 0;
}


G. A/B Matrix

题意:
n,m,a,b给定n,m,a,b
nm你需要找到一个n*m的矩阵
a1b10要求矩阵的每行恰有a个1,每列恰有b个1,其余为0
1如果存在构造出来,否则输出-1
题解:
1先判断-1的情况
1可以用两种情况判断所有1的个数
a1nna如果看行,每行有a个1,一共n行,共有n*a
b1mmb如果看列,每列有b个1,一共m列,共m*b
如果这两个不相等,说明不能构造
使如果可以构造,那就使每行进行错位构造
a第一行构造前a个,第二行继续,如果到了最后一个就重新在第一个构造,直到最后一行
AC代码

/*
    Author:zzugzx
    Lang:C++
    Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

int g[100][100];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int _;
    cin>>_;
    while(_--){
        int n,m,a,b;
        cin>>n>>m>>a>>b;
        memset(g,0,sizeof g);
        if(n*a!=m*b){cout<<"NO"<<endl;continue;}
        cout<<"YES"<<endl;
        int x=0;
        for(int i=0;i<n;i++)
            for(int j=0;j<a;j++){
                g[i][x++]=1;
                if(x==m)x=0;
            }
        for(int i=0;i<n;i++,cout<<endl)
            for(int j=0;j<m;j++)
                cout<<g[i][j];
    }
    return 0;
}


H. Binary Median

题意:
02m1从0到2^m-1的所有二进制数
n去掉其中给定的n个,进行字典序排序
(k1)/2输出(k-1)/2的向下取整位置的二进制数
题解:
字典序排序其实就是按二进制数化为十进制数的大小排序
将给定的二进制数化为十进制数放入数组
upperbound然后进行二分,对每种情况用upperbound去除掉该情况的去掉的数
然后直到找到所求的位置为止
然后转化成二进制输出
AC代码

/*
    Author:zzugzx
    Lang:C++
    Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

ll a[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int _;
    cin>>_;
    while(_--){
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            string s;
            cin>>s;
            a[i]=0;
            for(int j=0;j<m;j++)
                a[i]=(a[i]<<1)|(s[j]=='1');
        }
        ll ok=((1ll<<m)-n+1)>>1;
        sort(a+1,a+1+n);
        ll l=0,r=(1ll<<m)-1,ans;
        while(l<=r){
            ll mid=l+r>>1;
            ll sz=upper_bound(a+1,a+1+n,mid)-(a+1);
            sz=mid+1-sz;
            if(sz>=ok)ans=mid,r=mid-1;
            else l=mid+1;
        }
        for(int i=m-1;i>=0;i--)
            cout<<((ans>>i)&1);
        cout<<endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章