Acwing第38场周赛题解

AcWing 4299. 删点

题目链接:AcWing 4299. 删点

第一题都是签到题,其实就是计算是否存在在y轴两边,是否有一边的点数小于等于1

代码如下:

#include <iostream>

using namespace std;

const int N = 110;
int n, l, r;

int main(){
    cin >> n;
    for(int i = 0; i < n; i++){
        int x, y;
        cin >> x >> y;
        if(x > 0)r++;
        else l++;
    }
    if(l <= 1 || r <= 1)puts("Yes");
    else puts("No");
    
    return 0;
}

AcWing 4300. 两种操作

题目链接:AcWing 4300. 两种操作

这道题其实并不难,只要找对了方向就好做了,他只有两个操作,即减1和乘2,反过来就相当于对m进行两种操作,即通过加1和除2得到n,为了能够令m更快的接近n,很明显我们需要通过先除法来进行操作,当m小于n时,我们在进行加法,但是在这个过程中,m可能为奇数,所以我们需要判断,当m位奇数时,需对其加1,以保证能整除,最后得到n。
当然还有一种情况,就是当n > m时,这是n只能通过减1的方式得到m,所以这种情况直接计算n - m即可。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int n, m, res;

int mid(){
    int k = 0;
    while(m > n){// 当m <= n时说明m已经很接近n且可以通过加一的操作得到n了
        if(m % 2){ //判断m是否为奇数
            m++;
            res++;//res用来计算中途+1的操作次数
        }
        m /= 2;
        k++;//k计算除2的操作次数
    }
    return k;
}

int main(){
    cin >> n >> m;
    if (n == m)cout << 0 << endl;//情况1: n == m
    else if(n > m)               //情况2: n > m 
        cout << n - m << endl;
    else{                        //情况3: n < m
        int b = m;
        int k = mid();           //因为除2的过程有点像二分,所以我取名为mid
        if(m == n)cout << k + res << endl; // 如果恰好等于则不需要再进行加1操作
        else if(m < n)cout << (n - m) + k + res << endl; // 否则还需加上最后加1的操作
    }
    
    return 0;
}

AcWing 4301. 截断数列

题目链接:AcWing 4301. 截断数列

这道题虽是困难题,但其实也并不算太难,方向还是很好想到的,就是编程实现的方法不同可能会遇到一些麻烦,就比如说将其转化为数字并用数组存储,这样就要处理一些特殊情况,实际上并不需要转换,直接用字符串的形式,它们对应的ASCLL码值计算也是一样的。

思路:

其实将其分成两组或两组以上和的大小相同的形式,我们很容易可以考虑到,先将它们的总和计算,然后在更具总和的因子进行分组即可,因为不能随便分,顺序还是一样的,所以我们对每个因子的情况对字符串进行遍历,如果能够组成这个数,那就可以。

代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;
int n, sum;
char s[N];

int main(){
    cin >> n >> s;
    for(int i = 0; i < n; i++){
        s[i] -= '0';
        sum += s[i];
    }
    
    for(int i = 2; i <= n; i++){
        if(sum % i == 0){//判断是否是因子
            int k = 0;
            int p = sum / i;   
            bool f = true;
            //遍历,查看是否能分成等分
            for(int j = 0; j < n; j++){
                k += s[j];
                //如果k已经大于p则说明不能,直接退出,并标记false
                if(k > p){
                    f = false;
                    break;
                }
                else if(k == p){//如果等于则归0,重新开始计算
                    k = 0;
                }
            }
            if(f){
                puts("YES");
                return 0;
            }
        }
    }
    puts("NO");
    return 0;
}
  • 26
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

友人苏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值