Codeforces Round #777 (Div. 2)(A-C)

A. Madoka and Math Dad

题意

已知一个数字n,求能构造出每一位数字相加和为n的最大的数字,并且相邻的数字不能相等且不能含0

思路

首先,数字位数越多,数字就越大,其次,要让位数越高的数字越大。那么,要让位数越大,且相邻数字不能相等,且不含0,那么这个数字只能由1和2组成。那么数字中包含几个1几个2呢?数字1和2又是如何排列的呢?我分为以下三种情况:
1. n % 3 = 0时,数字n是3的倍数,那么ans就由n / 3个“21”组成;
2. n % 3 = 1时,这时会在数字末尾多一个1,那么ans就由n / 3个“12”加上一个1组成;
3. n % 3 = 2时,这时会在数字末尾多一个2,那么ans就由n / 3个“21”加上一个2组成。

#include <iostream>

using namespace std;
int t,n;

int main()
{
    cin >> t;
    while(t --){
        cin >> n;
        int x = n / 3;
        if(n % 3 == 0){
            while(x --) cout << 21;
            cout << endl;
        }
        else if(n % 3 == 1){
            while(x --) cout << 12;
            cout << 1 << endl;
        }
        else{
            while(x --) cout << 21;
            cout << 2 << endl;
        }
    }
    return 0;
}

B. Madoka and the Elegant Gift

题意
没有被包含的矩阵叫nice矩阵,如果一个图标里的任意两个nice矩阵相交那就输出NO,否则输出YES

思路
遍历二维数组,如果存在直角(即有两个nice矩阵相交),那么输出NO,否则输出YES,如图所示的四种情况:

四种情况

#include <bits/stdc++.h>

using namespace std;
int t;
int a[110][110];

bool check(int i,int j)
{
    if(a[i][j] + a[i + 1][j] + a[i][j + 1] == 3 && a[i + 1][j + 1] == 0) return true;
    else if(a[i][j] + a[i - 1][j] + a[i][j + 1] == 3 && a[i - 1][j + 1] == 0) return true;
    else if(a[i][j] + a[i][j - 1] + a[i + 1][j] == 3 && a[i + 1][j - 1] == 0) return true;
    else if(a[i][j] + a[i][j - 1] + a[i - 1][j] == 3 && a[i - 1][j - 1] == 0) return true;
    return false;
}

int main()
{
    cin >> t;
    while(t --){
        int n,m,flag = 0;
        char c;
        memset(a,0,sizeof(a));
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i ++){
            for(int j = 1;j <= m;j ++){
                cin >> c;
                a[i][j] = c - '0';
            }
        }
        for(int i = 1;i <= n;i ++){
            for(int j = 1;j <= m;j ++){
                if(check(i,j)){
                    flag = 1;
                }
            }
        }
        if(flag == 1) puts("NO");
        else puts("YES");
    }
    return 0;
}

C. Madoka and Childish Pranks
题意

给你一个需要构成的图,黑色是1,白色是0,要求你操作n*m次之内从全是0的图得到目标图,操作是选择一个任意长度和宽度的矩阵,把左上角变成0,然后和0相邻的全是1,和1相邻的全是0。

思路

从最后一行最后一个开始涂,遇到黑色的就开始涂,白色的不用管。每次都涂大小为1×2的矩阵,可以涂长为1宽为2的矩阵,也可以涂长为2宽为1的矩阵。注意如果所给的矩阵第一行第一个数字就是黑色的,那么这时无论怎么涂都得不到所给矩阵,这时输出-1。具体情况具体处理。一定要注意最后还让输出操作次数,而且让输出的是每次操作的子矩形的左上角和右下角坐标,而不是每个坐标处的操作次数!

#include <bits/stdc++.h>

using namespace std;
int t;
int a[110][110],b[110][110];

struct P{
    int x,y,p,q;
};
vector <P> c;


int main()
{
    cin >> t;
    while(t --){
        int n,m,flag = 0;
        cin >> n >> m;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        c.clear();
        char ch;
        for(int i = 1;i <= n;i ++){
            for(int j = 1;j <= m;j ++){
                cin >> ch;
                a[i][j] = ch - '0';
            }
        }
        if(a[1][1] == 1){
            puts("-1");
            continue;
        }
        for(int i = n;i >= 1;i --){
            for(int j = m;j >= 1;j --){
                if(a[i][j] == 1){
                    if(a[i][j - 1] == 0 && j > 1){
                        //c[i][j] ++,c[i][j - 1] ++;
                        c.push_back({i,j,i,j - 1});
                        b[i][j] = 1,b[i][j - 1] = 0;
                    }
                    else if(a[i - 1][j] == 0 && i > 1){
                        //c[i][j] ++,c[i - 1][j] ++;
                        c.push_back({i,j,i - 1,j});
                        b[i][j] = 1,b[i - 1][j] = 0;
                    }
                    else if(a[i][j - 1] == 1){
                        //c[i][j] ++,c[i][j - 1] ++;
                        c.push_back({i,j,i,j - 1});
                        b[i][j] = 1,b[i][j - 1] = 0;
                    }
                    else if(a[i - 1][j] == 1){
                        //c[i][j] ++,c[i - 1][j] ++;
                        c.push_back({i,j,i - 1,j});
                        b[i][j] = 1,b[i - 1][j] = 0;
                    }
                }
            }
        }
        for(int i = 1;i <= n;i ++){
            for(int j = 1;j <= m;j ++){
                if(a[i][j] != b[i][j]){
                    puts("-1");
                    flag = 1;
                    break;
                }
            }
        }
        if(flag) continue;
        else{
                cout << c.size() << endl;
            for(int i = 0;i < c.size();i ++){
                cout << c[i].p << ' ' << c[i].q << ' ' << c[i].x << ' ' << c[i].y << endl;
            }
        }

    }
    return 0;
}

这是我打的第四场cf,希望可以一直坚持下去~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小王超能吃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值