Codeforces Round #644 (Div. 3)题解

题目链接

A. Minimal Square

题意:
给 一 个 长 宽 分 别 为 a , b 的 矩 形 给一个长宽分别为a,b的矩形 ab
问 两 个 矩 形 放 在 一 个 正 方 形 内 , 正 方 形 的 面 积 最 小 为 多 少 问两个矩形放在一个正方形内,正方形的面积最小为多少
题解:
分 别 看 矩 形 的 长 和 宽 拼 到 一 起 的 情 况 分别看矩形的长和宽拼到一起的情况
长 拼 到 一 起 的 边 为 a , 2 ∗ b 长拼到一起的边为a,2*b a,2b
宽 拼 到 一 起 的 边 为 b , 2 ∗ a 宽拼到一起的边为b,2*a b,2a
同 种 情 况 内 取 最 大 边 , 然 后 这 两 种 情 况 取 最 小 同种情况内取最大边,然后这两种情况取最小
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数组,分成两个数列 n
使 得 一 个 数 列 的 最 大 值 和 另 一 个 数 列 的 最 小 值 差 最 小 使得一个数列的最大值和另一个数列的最小值差最小 使
求 出 最 小 值 求出最小值
题解:
直 接 数 组 排 序 , 前 i 个 一 组 , i + 1 到 n 一 组 直接数组排序,前i个一组,i+1到n一组 ii+1n
用 第 二 组 的 最 小 值 减 第 一 组 的 最 大 值 就 是 结 果 用第二组的最小值减第一组的最大值就是结果
所 以 直 接 排 序 后 求 相 邻 数 的 差 所以直接排序后求相邻数的差
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,则可以组成一对 1
给 n 个 数 ( n 为 偶 数 ) , 问 能 否 使 得 每 个 数 都 配 对 给n个数(n为偶数),问能否使得每个数都配对 nn使
题解:
由 于 n 为 偶 数 , 那 么 奇 数 个 数 和 偶 数 个 数 奇 偶 性 相 同 由于n为偶数,那么奇数个数和偶数个数奇偶性相同 n
如 果 都 为 偶 , 直 接 各 自 配 对 即 可 如果都为偶,直接各自配对即可
如 果 为 奇 , 看 是 否 都 有 一 对 奇 数 和 偶 数 相 差 为 1 配 对 如果为奇,看是否都有一对奇数和偶数相差为1配对 1
如 果 找 不 到 就 N O 如果找不到就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 n
找 一 个 1 − k 的 数 , 使 得 这 个 数 乘 p ( p 为 整 数 ) 为 n 找一个1-k的数,使得这个数乘p(p为整数)为n 1k使ppn
求 最 小 p 求最小p p
题解:
直 接 枚 举 n 的 所 有 因 子 x , 如 果 这 个 因 子 在 1 − k 直接枚举n的所有因子x,如果这个因子在1-k nx1k
那 么 计 算 一 下 n / x , 并 取 最 小 值 那么计算一下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

题意:
给 出 n 个 字 符 串 , 长 度 都 为 m 给出n个字符串,长度都为m nm
是 否 能 找 到 一 个 字 符 串 是否能找到一个字符串
这 个 字 符 串 和 这 n 个 字 符 串 的 每 一 个 最 多 只 有 一 个 不 同 的 字 符 这个字符串和这n个字符串的每一个最多只有一个不同的字符 n
题解:
直 接 D F S 暴 力 枚 举 每 一 个 字 符 直接DFS暴力枚举每一个字符 DFS
搜 索 的 同 时 用 二 进 制 记 录 一 个 状 态 搜索的同时用二进制记录一个状态
记 录 第 i 个 字 符 串 能 否 再 出 现 不 同 字 符 记录第i个字符串能否再出现不同字符 i
如 果 为 1 则 能 , 否 则 不 能 如果为1则能,否则不能 1
如 果 出 现 且 对 应 状 态 为 1 , 置 0 , 如 果 对 应 状 态 为 0 直 接 进 行 r e t u r n 如果出现且对应状态为1,置0,如果对应状态为0直接进行return 100return
然 后 每 次 进 行 回 溯 , 记 录 当 前 字 符 串 , 找 到 后 r e t u r n 输 出 然后每次进行回溯,记录当前字符串,找到后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 n,m,a,b
你 需 要 找 到 一 个 n ∗ m 的 矩 阵 你需要找到一个n*m的矩阵 nm
要 求 矩 阵 的 每 行 恰 有 a 个 1 , 每 列 恰 有 b 个 1 , 其 余 为 0 要求矩阵的每行恰有a个1,每列恰有b个1,其余为0 a1b10
如 果 存 在 构 造 出 来 , 否 则 输 出 − 1 如果存在构造出来,否则输出-1 1
题解:
先 判 断 − 1 的 情 况 先判断-1的情况 1
可 以 用 两 种 情 况 判 断 所 有 1 的 个 数 可以用两种情况判断所有1的个数 1
如 果 看 行 , 每 行 有 a 个 1 , 一 共 n 行 , 共 有 n ∗ a 如果看行,每行有a个1,一共n行,共有n*a a1nna
如 果 看 列 , 每 列 有 b 个 1 , 一 共 m 列 , 共 m ∗ b 如果看列,每列有b个1,一共m列,共m*b b1mmb
如 果 这 两 个 不 相 等 , 说 明 不 能 构 造 如果这两个不相等,说明不能构造
如 果 可 以 构 造 , 那 就 使 每 行 进 行 错 位 构 造 如果可以构造,那就使每行进行错位构造 使
第 一 行 构 造 前 a 个 , 第 二 行 继 续 , 如 果 到 了 最 后 一 个 就 重 新 在 第 一 个 构 造 , 直 到 最 后 一 行 第一行构造前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

题意:
从 0 到 2 m − 1 的 所 有 二 进 制 数 从0到2^m-1的所有二进制数 02m1
去 掉 其 中 给 定 的 n 个 , 进 行 字 典 序 排 序 去掉其中给定的n个,进行字典序排序 n
输 出 ( k − 1 ) / 2 的 向 下 取 整 位 置 的 二 进 制 数 输出(k-1)/2的向下取整位置的二进制数 (k1)/2
题解:
字 典 序 排 序 其 实 就 是 按 二 进 制 数 化 为 十 进 制 数 的 大 小 排 序 字典序排序其实就是按二进制数化为十进制数的大小排序
将 给 定 的 二 进 制 数 化 为 十 进 制 数 放 入 数 组 将给定的二进制数化为十进制数放入数组
然 后 进 行 二 分 , 对 每 种 情 况 用 u p p e r b o u n d 去 除 掉 该 情 况 的 去 掉 的 数 然后进行二分,对每种情况用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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值