codeforces(div 2 #711)

这篇博客探讨了两个算法问题的解决思路。A-GCDSum中,通过判断n、n+1、n+2与各自数位之和的GCD是否大于1来找到满足条件的数字。B-BoxFitting问题中,采用贪心策略,按方块大小排序,利用优先队列寻找最小高度的盒子布局。
摘要由CSDN通过智能技术生成

A - GCD Sum

题意:
第一个多组输入
第二个给你一个数字n,然后让你判断什么时候n和他自己每一个数位的和可以出来gcd大于1

思路:
这里不提供严格的数学证明,我们可以根据几组数据推导可以知道,我们只需要判断n,n+1,n+2这个三个数字即可
感兴趣的师傅们可以推导证明试试
然后我们就可以写代码判断了
AC代码如下

#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[20];
bool solve(int n)
{
    memset(a,0,sizeof(a));
    int temp=n;
    int cnt=1;
    while(temp)
    {
        a[cnt++]=temp%10;
        temp/=10;
    }
    int sum=0;
    for(int i=1;i<cnt;i++)
    {
        sum+=a[i];
    }
    if(__gcd(n,sum)>1)return true;
    else return false;
}

signed main()
{
    int T;
    scanf("%lld",&T);
    while(T--)
    {
        int n;
        scanf("%lld",&n);
        if(solve(n))
        {
            printf("%lld\n",n);
        }
        else if(solve(n+1))
        {
            printf("%lld\n",n+1);
        }
        else if(solve(n+2))
        {
            printf("%lld\n",n+2);
        }
    }
    return 0;
}

B - Box Fitting

题意:
第一个多组输入
第二个给你n个数字,和二维平面的一个宽度
我们需要判断的是他的最小的高是多少

思路:
首先我们第一个想法肯定是贪心
我们该怎么去贪心这个东西
首先我们要把我们的方块从大到小排一个序
这里我是用的是multiset使他的复杂度为log(n)
然后这个是存我们输入的方块
第二个我用了一个大顶堆的优先队列进行操作
这个我每次先把这个清空吗,然后我push一个0进去
意义就是第一次什么都没有操作的时候的样子,这个存储的是每层剩余的空位置
紧接着我们一个个判断,从我们的multiset的第一个开始判断,如果他小于这个剩余的空位置,我们就可以把它输进去,我们把之前保存的那个空位置直接pop()掉,然后我们紧接着把新的空位置输入进去,什么是新的空位置,就是原来的空位置减去我们刚才输入进去的方块
然后我们紧接着进行下一个方块的判断,如果我们这次的这个方块它如果比我们这层所剩下的空位置要是大的话,我们不得以就是得再开一层来存放我们的这个方块,然后既然我们又开了一层,我们的层数这里我用cnt表示,所以就是cnt++
紧接着我们把我们新开辟的一层存入我们的大顶堆的优先队列里面,这个存入的就是我们的宽度减去我们刚才的那个木块的一个大小,这样我们的思路就完成了,当我们循环完了最后一个方块之后,我们不就是可以知道我们究竟需要几层么,这个就是这个思路,请仔细读完,想明白之后很简单,下面的AC代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
//int a[N];
multiset<int,greater<int> >a;// n
priority_queue<int>q;// leave
signed main()
{
    int T;
    scanf("%lld",&T);
    while(T--)
    {
        a.clear();
        while(!q.empty())q.pop();
        int temp=q.top();
//        printf("%lld\n",temp);
        multiset<int,greater<int> >::iterator it;
        int n,w;
        scanf("%lld%lld",&n,&w);
        for(int i=1;i<=n;i++)
        {
            int temp;
            scanf("%lld",&temp);
            a.insert(temp);
        }
        q.push(0);
//        for(it=a.begin();it!=a.end();it++)
//            printf("%lld ",*it);
        int cnt=0;
        for(it=a.begin();it!=a.end();it++)
        {
            int temp=q.top();
            q.pop();
            if(temp<*it)
            {
                q.push(temp);
                q.push(w-*it);
                cnt++;
            }
            else
            {
                q.push(temp-*it);
            }
        }
        printf("%lld\n",cnt);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值