Codeforces Round #711 (Div. 2) 补题A B

A.GCD Sum

在这里插入图片描述

分析: 只需要寻找三次即可。
证明: 考虑一个数被 3 3 3整除, 3 , 6 , 9 , 12 , 15 , ⋯   , 3 ∗ k 3,6,9,12,15,\cdots,3*k 3,6,9,12,15,,3k,即每一个被3整除的数区间长度都为 3 3 3,所以对于任意一个数,至多需要操作 3 3 3次就可以找到下一个被 3 3 3整除的数。
至于为什么要找被 3 3 3整除的数,因为被 3 3 3整除的数都有一个性质:各位之和也被 3 3 3整除。这样就可以满足题目条件,一个数字与各位数字之和的 gcd \text{gcd} gcd不为 1 1 1而为3。
利用数学归纳法证明这一性质:
设有整数 a b ab ab 3 3 3整除,
则有 a b = a ∗ 10 + b = 9 ∗ a + a + b ab=a*10+b=9*a+a+b ab=a10+b=9a+a+b
要被 3 3 3整除必须有 ( a + b ) m o d    3 = 0 (a+b)\mod3=0 (a+b)mod3=0
设有整数 a b c abc abc 3 3 3整除,
则有 a b c = a ∗ 100 + b ∗ 10 + c = 99 ∗ a + 9 ∗ b + a + b + c abc=a*100+b*10+c=99*a+9*b+a+b+c abc=a100+b10+c=99a+9b+a+b+c
要被 3 3 3整除必须有 ( a + b + c ) m o d    3 = 0 (a+b+c)\mod3=0 (a+b+c)mod3=0
设整数 a ⋯ k a\cdots k ak被3整除,
则有 a ⋯ k = 99 ⋯ 9 ∗ a + ⋯ + a + ⋯ + k a\cdots k=99\cdots9*a+\cdots+a+\cdots+k ak=999a++a++k
要被 3 3 3整除必须有 ( a + ⋯ + k ) m o d    3 = 0 (a+\cdots+k)\mod3=0 (a++k)mod3=0
设整数 a ⋯ k ( k + 1 ) a\cdots k(k+1) ak(k+1)被3整除,
则有 a ⋯ k ( k + 1 ) = 99 ⋯ 9 ∗ a + ⋯ + a + 9 ∗ k + ⋯ + k + ( k + 1 ) a\cdots k(k+1)=99\cdots9*a+\cdots+a+9*k+\cdots+k+(k+1) ak(k+1)=999a++a+9k++k+(k+1)
要被 3 3 3整除必须有 ( a + ⋯ + k + ( k + 1 ) ) m o d    3 = 0 (a+\cdots+k+(k+1))\mod3=0 (a++k+(k+1))mod3=0

代码:

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b){
    
    
	return b==0?a:gcd(b,a%b);
}
int t;
LL n;
int main(){
    
    
    cin>>t;
    while(t--){
    
    
        cin>>n;
        LL wei=0,tmp=n;
        while(tmp){
    
    
            wei+=tmp%10;
            tmp/=10;
        }
        while(gcd(n,wei)==1){
    
    
            n++;
            tmp=n;
            wei=0;
            while(tmp){
    
    
                wei+=tmp%10;
                tmp/=10;
            }
        }
        cout<<n<<endl;
    }
}

B. Box Fitting

在这里插入图片描述
分析: 先初始化宽度为 k k k,高度为 1 1 1,将方格从大到小排序,每次取最大的方格,往里面放,如果放不下去,那么就新增高度,因为显然长度大的方块比长度小的方块最优。
这里排序可以利用 2 2 2的幂次方这一性质,从大到小枚举,题目数据范围为 1 e 9 1e9 1e9,故而方块的幂只能 ≤ 19 \le 19 19

#include<bits/stdc++.h>
using namespace std;
int t,n,w,x;
int main(){
    
    
    cin>>t;
    while(t--){
    
    
        vector<int> a(20);
        cin>>n>>w;
        int cnt=1,res=w;
        for(int i=0;i<n;i++){
    
    
            cin>>x;
            a[log2(x)]++;
        }
        for(int i=0;i<n;i++){
    
    
            int flag=-1;
            for(int j=19;j>=0;j--){
    
    
                if(a[j]&&(1<<j)<=res){
    
    
                    flag=j;
                    break;
                }
            }
            if(flag==-1){
    
    
                res=w;
                cnt++;
                for(int j=19;j>=0;j--){
    
    
                    if(a[j]&&(1<<j)<=res){
    
    
                        flag=j;
                        break;
                    }
                }
            }
            a[flag]--;
            res-=(1<<flag);
        }
        cout<<cnt<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/messywind/article/details/115348898