栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Codeforces Round #786 (Div. 3)题解A~F

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Codeforces Round #786 (Div. 3)题解A~F

Codeforces Round #786 (Div. 3) A. Number Transformation 原题:

题目大意:

给你一个x,y,问你能否对x通过乘以a次b可以得到y的方案,可以输出a和b即可(答案不唯一),如果不可以,输出0 0。

思路分析:

代码:
#include 
#include 
#include 
using namespace std;
int t, a, b, x, y;
int main()
{
    cin >> t;
    while(t --){
        cin >> x >> y;
        if(y % x){
            cout<<"0 0"<<'n';
        }
        else{
            cout<<"1 "< 
B. Dictionary 
原题: 


题目大意:

根据题意对给定的字符串输出其对应的下标即可。

思路分析:

代码:
#include 
#include 
#include 
using namespace std;
int t;
string tmp;
int main()
{
    cin >> t;
    while(t -- ){
        cin>>tmp;
        int ans = 0;
        ans = (tmp[0] - 'a') * 25;
        if(tmp[1] > tmp[0])ans += tmp[1] - 'a';
        else ans += tmp[1] - 'a' + 1;
        cout << ans << 'n';
    }
    return 0;
}
C. Infinite Replacement 原题:

题目大意:

给定一个字符串s和字符串t,字符串都是由a字符构成,我们通过t取替换s中字符a的地方,能够得到多少方案。如果会无限循环输出-1,反之输出方案即可。

思路分析:

分类讨论:

1)如果t = ‘a’; 那么就一种方案 1
2)如果t 中有’a’, 每次替换s的时候都会多一个a,会无限循环,那么就 - 1
3)如果t 中没有a, 就是每次替换s的方案数,即 2^len

代码:
#include 
#include 
#include 
using namespace std;
int q;
string s, t;
long long jc(int n){
    long long ans = 1;
    for(int i = 1; i <= n; i ++)ans *= 2;
    return ans;
}
int main()
{
    cin >> q;
    while(q --){
        cin >> s;
        cin >> t;
        int flag = 0, len = t.size(), len2 = s.size();
        for(int i = 0; i < len; i ++){
            if(t[i] == 'a'){
                flag = 1;
                break;
            }
        }
        if(t.size() == 1 && flag)cout<<"1"<<'n';
        else if(flag)cout<<"-1"<<'n';
        else {
            long long ans = jc(len2);
            cout << ans<< 'n';
        }
    }
    return 0;
}


D. A-B-C Sort 原题:


题目大意:

先后对a数组和b数组进行操作,问能否使得得到的c是非递减的。

操作:

思路分析:

对a数组考虑,可以发现,最前面的数肯定是先被c取到放到最后面的数

如果要让最后的c数组是非递减的,必须满足:

如果初始a数组的长度n是偶数:t == 2;

如果初始a数组的长度n是奇数:t == 1;

1)t == 1时,下标idx数的大小要小于等于idx + 2和idx + 3

  1. t == 2时,下标idx数的大小要小于等于idx + 1和idx + 2
代码:
#include 
#include 
#include 
using namespace std;
const int N = 1e6 + 5;
int t, n;
int a[N];
int main()
{
    cin >> t;
    while(t --){
        cin >> n;
        for(int i = 1; i <= n; i ++)cin >> a[i];
        int flag = 1, t = 1;
        if(n % 2)t = 2;
        for(int idx = 1; idx <= n; idx ++){
            if(t == 1){
                t = 2;
                if(a[idx] > a[idx + 2] && idx + 2 <= n){
                    flag = 0;
                    break;
                }
                if(a[idx] > a[idx + 3] && idx + 3 <= n){
                    flag = 0;
                    break;
                }
            }
            else if(t == 2){
                t = 1;
                if(a[idx] > a[idx + 1] && idx + 1 <= n){
                    flag = 0;
                    break;
                }
                if(a[idx] > a[idx + 2] && idx + 2 <= n){
                    flag = 0;
                    break;
                }
            }
        }
        if(flag)cout << "YES" << 'n';
        else cout << "NO" << 'n';
        
    }
    return 0;
}
E. Breaking the Wall 原题:



题目大意:

有n面墙,问你摧毁任意两座(可以不相连)需要的最少操作数。

每一次操作:可以选择任意一座墙造成2点伤害,并且其左右相邻的墙同时收到1点伤害。

思路分析:

分类讨论一下:

1)攻击使相邻两个使两个摧毁:

​ 最优:令两个墙中强度最小为minn,最大为maxx

再次讨论:

1、如果minn * 2 <= maxx

​ 我们直接可以通过用2伤害攻击强大最大的墙,当最大的墙摧毁时,那么较小的那面墙也肯定摧毁了。

2、如果minn * 2 > maxx

​ 用2伤害直接攻击最大强度的墙,肯定会达到两面墙强度相等的时候,然后依次轮流每次攻击一面墙,两面墙的差最多为1,让输出达到最大化,结果肯定能够同时到达0 或者 一个为0 一个为 1,后者就直接再攻击依次就好了。

for(int i = 1; i <= n - 1; i ++){
        int maxx = -N, minn = N;
        maxx = max(a[i], a[i + 1]);
        minn = min(a[i], a[i + 1]);
        if(minn * 2 <= maxx){
            s1 = min(s1, (maxx + 1) / 2);
        }
        else{
            s1 = min(s1, (a[i] + a[i + 1] + 2) / 3);
        }
    }

2)通过攻击中间一个摧毁其旁边两面墙:

最优:枚举所有情况,攻击中间一个墙,如果左右两边有一面墙强度为0了,就直接用2伤害去攻击另一边的墙, 取最小值。

for(int i = 1; i <= n - 2; i ++){
        int tmp = min(a[i], a[i + 2]) + (abs(a[i + 2] - a[i]) + 1) / 2;
        s2 = min(s2, tmp);
    }

3)直接攻击摧毁两个不相邻的墙

​ 最优情况就是找两个强度最小min1和min2的墙,让后分别通过两点伤害就他们摧毁即可。

(min1 + 1) / 2 + (min2 + 1) / 2

因为1) 2) 3 )就包含了所有情况,所以答案即取1) 2) 3)的最小值

代码:
#include 
#include 
#include 
using namespace std;
const int N = 1e6 + 10;
int n, s1 = N, s2 = N, ans = N;
int a[N];
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++)cin >> a[i];

    for(int i = 1; i <= n - 1; i ++){
        int maxx = -N, minn = N;
        maxx = max(a[i], a[i + 1]);
        minn = min(a[i], a[i + 1]);
        if(minn * 2 <= maxx){
            s1 = min(s1, (maxx + 1) / 2);
        }
        else{
            s1 = min(s1, (a[i] + a[i + 1] + 2) / 3);
        }
    }

    for(int i = 1; i <= n - 2; i ++){
        int tmp = min(a[i], a[i + 2]) + (abs(a[i + 2] - a[i]) + 1) / 2;
        s2 = min(s2, tmp);
    }

    sort(a + 1, a + n + 1);
    ans = min({s1, s2, (a[1] + 1) / 2 + (a[2] + 1) / 2});

    cout << ans << 'n';

    return 0;
}
F. Desktop Rearrangement 原题:


题目大意:

加删图标,问排列整齐最少需要几步。

整齐:从左往右依次排数列,排满一列排下列。

思路分析:

分类讨论,维护不需要排的数量,答案就是总图标数减去不需要排的图标数。

代码:
#include 
#include 
#include 
#include 
using namespace std;
typedef pair PII;
const int N = 1e3 + 5, M = 1e6 + 5;
int n, m, q, sum = 0;
char g[N][N];
mapmp;
int main()
{
    cin >> n >> m >> q;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j ++){
            cin >> g[i][j];
            if(g[i][j] == '*'){
                sum ++;
                mp[{i, j}] = 1;
            }
        }
    }
    //统计在范围内的点数
    int cnt = 0;
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            if(mp[{i, j}] == 1 && (j - 1) * n + i <= sum)cnt ++;
        }
    }

    //最大能排到的位置ii jj
    int ii, jj;
    if(sum % n == 0){
        ii = n;
        jj = sum / n;
    }
    else {
        ii = sum % n;
        jj = sum / n + 1;
    }

    //cout<
        int x, y, tmp, ans;
        cin >> x >> y;
        tmp = n * (y - 1) + x;
        // cout<<"tmp:"< sum && mp[{x, y}] == 1){
            sum --;
            mp[{x, y}] = 0;
            if(mp[{ii, jj}] == 1)cnt --;
            if(ii == 1){
                ii = n;
                jj --;
            }
            else{
                ii --;
            }
            
        }
        else if(tmp <= sum && mp[{x, y}] == 1){
            sum --;
            cnt --; 
            mp[{x, y}] = 0;
            
            if(mp[{ii, jj}] == 1 && (x != ii || y != jj))cnt --;

            if(ii == 1){
                ii = n;
                jj --;
            }
            else{
                ii --;
            }
           
        }
        else if(tmp <= sum && mp[{x, y}] == 0){
            cnt ++; sum ++;mp[{x, y}] = 1;
            if (ii == n){
                ii = 1;
                jj += 1;
            }
            else {
                ii ++;
            }
            if(mp[{ii, jj}] == 1 )cnt++;
            
        }
        else if(tmp > sum && mp[{x, y}] == 0){
            sum ++;mp[{x, y}] = 1;
            if (ii == n){
                ii = 1;
                jj += 1;
            }
            else {
                ii ++;
            }
            if(mp[{ii, jj}] == 1 )cnt++;
            
        }
        ans = sum - cnt;
        cout << ans << 'n';
    }
    return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/864629.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号