Educational Codeforces Round 173 (Rated for Div. 2) A~D

A. Coin Transformation

链接:Problem - A - Codeforces

算法:模拟 枚举

思路:记录当前每个硬币大小 当每个硬币大小大于3时候 将硬币个数翻倍 再将每个硬币大小除以四 枚举直到硬币大小小于3时 输出硬币个数

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll Q = 2e5 + 9;
const ll MOD = 1e9+7;
ll a[Q];
void solve(){
    ll n;cin>>n;
    ll ans=1;
    while(n>3){
        n/=4;
        ans*=2;
    }
    cout<<ans<<"\n";
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll _ = 1;cin>>_;
    while(_--){
        solve();
    }
    return 0;
}

B. Digits

链接:Problem - B - Codeforces

算法:打表

思路:打表 找出1到18个每个不同数字并列时在多少个的时候可以整除 3和7和9。

1:所有数都可以被1整数。

3:当该数字个数为3的倍数的时候 或者 该数字可以整除3的时候则符合条件(3,6,9)

5:必须当该数为5的时候则符合条件

7:若该数为7则符合条件

当该数不为7 该数字个数为6的倍数的时候则符合条件

9:若该数为9则符合条件

若该数为3或者6的时候 该数字个数为3的倍数即可 

若该数不为3或6或9的时候 该数字个数为9的倍数即可

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll Q = 2e5 + 9;
const ll MOD = 1e9+7;
void solve(){
    ll n,d;cin>>n>>d;
    cout<<1<<" ";
    if(n>=3 or d%3==0){
        cout<<3<<" ";
    }
    if(d==5){
        cout<<5<<" ";
    }
    if(n>=3 or d==7){
        cout<<7<<" ";
    }
    if((n>=6 or d==9) or (n>=3 and (d==3 or d==6))){
        cout<<9<<" ";
    }
    cout<<"\n";
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll _ = 1;cin>>_;
    while(_--){
        solve();
    }
    return 0;
}

C. Sums on Segments

链接:Problem - C - Codeforces

算法:前缀和

思路:找出不为1和-1的数的位置为it 然后将该数组分成两部分,分别求出左边和右边的最小字段和 和最大字段和 然后将最小值到最大值 全部加入答案,然后从it位置 往左右两边跑 找出往左边走的最大前缀和与最小前缀和 往右边走的最大前缀和和最小前缀和。然后将it位置的数字加入左右两边的最小值 还有最大值 然后将这个最小值到最大值区间加入答案

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll Q = 2e5 + 9;
const ll MOD = 1e9+7;
ll a[Q];
set<ll> an;
void solve(){
    ll n;cin>>n;
    ll it=0;
    for (ll i = 1; i <= n; i++){
        cin>>a[i];
        if(a[i]!=-1 and a[i]!=1) it=i;
    }
    an.clear();
    an.insert(0);
    ll mx=0;
    ll now=0;
    ll ans=0;
    for (ll i = 1; i < it; i++)
    {
        now+=a[i];
        mx=min(mx,now);
        ans=max(ans,now-mx);
    }
    for (ll i = 0; i <= ans; i++)
    {
        an.insert(i);
    }
    mx=0;
    now=0;
    ans=0;
    for (ll i = 1; i < it; i++)
    {
        now+=a[i];
        mx=max(mx,now);
        ans=min(ans,now-mx);
    }
    for (ll i = 0; i >= ans; i--)
    {
        an.insert(i);
    }
       mx=0;
       now=0;
       ans=0;
    for (ll i = it+1; i <= n; i++)
    {
        now+=a[i];
        mx=min(mx,now);
        ans=max(ans,now-mx);
    }
    for (ll i = 0; i <= ans; i++)
    {
        an.insert(i);
    }
    mx=0;
    now=0;
    ans=0;
    for (ll i = it+1; i <= n; i++)
    {
        now+=a[i];
        mx=max(mx,now);
        ans=min(ans,now-mx);
    }
    for (ll i = 0; i >= ans; i--)
    {
        an.insert(i);
    }
    ll sum=0;
    ll rmax=0,rmin=0;
    ll lmax=0,lmin=0;
    for (ll i = it+1; i <= n; i++)
    {
        sum+=a[i];
        rmax=max(rmax,sum);
        rmin=min(rmin,sum);
    }sum=0;
    for (ll i = it-1; i >= 1; i--)
    {
        sum+=a[i];
        lmax=max(lmax,sum);
        lmin=min(lmin,sum);
    }
    for (ll i = a[it]; i >= a[it]+lmin+rmin; i--)
    {
        an.insert(i);
    }
    for (ll i = a[it]; i <= a[it]+lmax+rmax; i++)
    {
        an.insert(i);
    }
    // cout<<lmin<<" "<<rmin<<"\n";
    // cout<<lmax<<" "<<rmax<<"\n";
    cout<<an.size()<<"\n";
    for(auto i:an) cout<<i<<" ";
    cout<<"\n";
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll _ = 1;cin>>_;
    while(_--){
        solve();
    }
    return 0;
}

D. Problem about GCD

链接:Problem - D - Codeforces

算法:枚举

思路:找出的A和B肯定能被G所整除 所以A可以写成 G*a , B是G*b,为了使得|A-B|最大 也就是让|a-b|也最大,为了让A和B的GCD=G 也就是让a和b的GCD=1即可,a和b的GCD等于1后 则A和B就只能被G所整除了,先把l靠近比它大的能被G所整除的数 r靠近比它小的能被G所整除的数 然后转换成l/G 和 r/G,然后先枚举长度 再枚举起点a的位置,暴力判断a和b是否gcd为1不是则更新起点 然后再更新长度,两个质数之间的距离log(1e18)所以枚举次数不会太多。

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll Q = 2e5 + 9;
const ll MOD = 1e9+7;
ll a[Q];
void solve(){
    ll l,r,g;cin>>l>>r>>g;
    l=(l/g+!!(l%g))*g;
    r=(r/g)*g;
    ll o=l/g,p=r/g;
    for (ll i = p-o ; i >= 0; i--)
    {
        for (ll j = o; j <= p; j++)
        {
            if(j+i>p) break;
            if(gcd(j,j+i)==1){
                cout<<j*g<<" "<<g*(j+i)<<"\n";
                return;
            }
        }
        
    }
    cout<<"-1 -1\n";
    
    
    
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll _ = 1;cin>>_;
    while(_--){
        solve();
    }
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值