Codeforces Round #644(Div.3) 题解

Posted lyfer233

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #644(Div.3) 题解相关的知识,希望对你有一定的参考价值。

本场Div3非常适合训练思维和手速。因为真的不算难,是我完整补完所有题目的一场CF了。

A题 Minimal Square

题意:

给出两块长度为a,宽度为b的矩阵,矩阵可以旋转自由拼接,但是两块矩阵不能相交,求能覆盖这两个矩阵的最小正方形面积。

思路:

仔细思考只有把矩阵的最长边固定,再把两个矩阵的短边拼在一块才会是最优的。简单证明一下 设a为长边 b为短边,那么拼接后只会有 三种可能  a + a , a + b, b + b。而影响正方形边长的因素是那个最长的边。即是 max(a, a + a, a + b, b + b),显然要让这个尽量小的话就把 a + a, a + b 去掉只比较 a和 b + b.

技术图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 int t;
 5  
 6 int main(){
 7     cin >> t;
 8     while(t--){
 9         int a, b;
10         cin >> a >> b;
11         int Now = min(a, b) + min(a, b);
12         Now = max(Now, max(a, b));
13         cout << Now * Now << endl;
14     }    
15     return 0;
16 }
AC Code

 

B题 Honest Coach

题意:

把n个数分成两组,让第一组的最大值 与 第二组的最小值的差 的绝对值最小。

思路:

思考一下就是把n个数排序,之后枚举切割点(在此把所有数分成两段,并且左端的最大值与右端的最小值是相邻的)。

技术图片
#include <bits/stdc++.h>
using namespace std;
 
int t;
int n;
int s[1005];
 
int main(){
    cin >> t;
    while(t--){
        cin >> n;
        for(int i = 1; i <= n; i++) cin >> s[i];
        sort(s + 1, s + 1 + n);
        int Min = 0x3f3f3f;
        for(int i = 2; i <= n; i++) Min = min(Min, abs(s[i] - s[i - 1]));
        cout << Min << endl;
    }
    return 0;
}
AC Code

C题 Similar Pairs

题意:

如果两个数有相同的奇偶性、或者两个数之差的绝对值为1,则称两个数是相似的。给出n个数,求是否将这n个数划分成n/2对相似的数。

思路:

 

D题 Buying Shovels

题意:

给出两个数n,k。你需要选择0~k之间的一个数,使其加和t次后恰好为n。 求t的最小值是多少?

思路:

显然我们要找的是n的因数p,同时要求t尽量小,所以这个p要尽量大。于是我们枚举n的因数t从1~根号n,同时这样意味着我们选择的是p是n / i,但必须保证这个 n / i值在k的范围内,否则p选择i,则t为n / i.

技术图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 typedef long long ll;
 5  
 6 int t;
 7 ll n, k;
 8  
 9 int main(){
10     cin >> t;
11     while(t--){
12         cin >> n >> k;
13         if(k >= n) cout << 1 << endl;
14         else{
15             ll Out = 1e9;
16             for(ll i = 1; i * i <= n && i <= k; i++){
17                 if(n % i == 0){
18                     if(n / i <= k) Out = min(Out, i);
19                     else Out = min(Out, n / i);
20                 }
21             }
22             cout << Out << endl;
23         }
24     }
25     return 0;
26 }
AC Code

 

E题 Polygon

题意:

一个n*n的格子,左侧和上侧各有n个炮台,初始阶段所有格子为0,每次炮台都可以发射一颗数字为1的炮弹,炮弹触及到边界或者格子数为1时停止并在当前格子生成1.给定了一个目标的状态,询问是否能通过这2n个炮台按照一定顺序发射炮弹来完成。

思路:

根据观察我们会发现,如果一个格子是1并且相邻的右格子和下面格子都为0的话,并且不是在边界上的格子的话。那么一定是不可行的。

技术图片
#include <bits/stdc++.h>
using namespace std;
 
int t;
int n;
char aim[55][55];
 
int main(){
    scanf("%d", &t);
    while(t--){
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%s", aim[i] + 1);
        }
        
        bool Can = true;
        
        for(int i = 1; i < n; i++)
            for(int j = 1; j < n; j++)
                if(aim[i][j] == 1 && aim[i+1][j] == 0 && aim[i][j+1] == 0 ) Can = false;
                
        if(Can) puts("YES");
        else puts("NO");
    }
    return 0;
}
AC Code

 

F题 Spy-string

题意:

 

思路:

 

G题A/B Matrix

题意:

 

思路:

H题 Binary Median

题意:

一共有2^m个长度为m的二进制字符串,按照从小到大的顺序排列。 例如m=3则按照 000 001 010 011 100 101 110 111排列。要求在删去n个二进制串后,输出第(k-1)/2个二进制串。 其中 1 <= n <= min(2 ^ m - 1, 100)  并且 m <= 60  k = 2 ^ m - n

思路:

观察样例,会发现如果删去的x(x<=n) 个二进制串在第 (k-1)/2 之后的话,不会产生任何影响。如果这删除的x个串在第 (k-1)/2 之前的话,那么就从第 (k-1)/2 位置开始后移X个位置。 (手动模拟一下样例会更好) 因为最多不超过100个n,所以最多移动100位,不会超时。

还有记得输入和输出的问题!

技术图片
#include <bits/stdc++.h>
using namespace std;
 
typedef unsigned long long ull;
int t;
ull Del[111];
 
int main(){
    ios::sync_with_stdio(false);
    cin >> t;
    while(t--){
        int n, m;
        memset(Del, 0, sizeof(Del));
        cin >> n >> m;
        
        for(int i = 0; i < n; i++){
            string x;
            cin >> x;
            reverse(x.begin(), x.end());
            ull now = 1;
            for(int j = 0; j < x.length(); j++){
                if(x[j] == 1) Del[i] += now;
                now <<= 1; 
            }
        }
        sort(Del, Del + n);
        ull k = pow(2, m) - n;
        ull Num = (k - 1) / 2;
        
        for(int i = 0; i < n; i++){
            if(Num >= Del[i]) Num ++;
            else break;
        }
        //cout << "Num : "  << Num  << endl;
        string ans;
        while(Num > 0){
            if(Num % 2 == 0) ans += "0";
            else ans += "1";
            Num >>= 1;
        }
        for(int i = m; i >= ans.length() + 1; i--) cout << 0;
        for(int i = ans.length() - 1; i >= 0; i--) cout << ans[i];
        cout << endl;
    }
    return 0;
}
AC Code

 

以上是关于Codeforces Round #644(Div.3) 题解的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #644 (Div. 3) A-F

Codeforces Round #644(Div.3) 题解

Codeforces Round #644 (Div. 3) H. Binary Median

Codeforces Round #644 (Div. 3) H. Binary Median

Codeforces Round #644 (Div. 3) G. A/B Matrix

Codeforces Round #705 (Div. 2)