Codeforces Round #667 (Div. 3)(A->E)

A:http://codeforces.com/contest/1409/problem/A

题意:

a,b,

每一步可a+k或a-k,1<=k<=10,a=b最少需要几步

解析:

优先+-10,不足的一定<10,一步即可

#include<bits/stdc++.h>
#include<map>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=5e3+10;
const int maxn2=1e9+10;
const int mod=1e9+10;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ll a,b;
        cin>>a>>b;
        if(a==b)
        {
            cout<<"0"<<endl;continue;
        }
        if(a<b)
        {
            ll cha=b-a;
            ll cnt1=cha/10;
            if(cha%10==0)
                cout<<cnt1<<endl;
            else
                cout<<cnt1+1<<endl;
        }
        else
        {
            ll cha=a-b;
            ll cnt1=cha/10;
            if(cha%10==0)
                cout<<cnt1<<endl;
            else
                cout<<cnt1+1<<endl;
        }
    }
}

B:http://codeforces.com/contest/1409/problem/B

题意:

a,b,x,y,n

操作最多n次,操作为:a-1或b-1

求操作后a*b的最小值

解析:

两种情况,分别算一下求最大值即可

1:先给a,余出来的给b

2:先给b,余出来的给a

#include<bits/stdc++.h>
#include<map>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=5e3+10;
const int maxn2=1e9+10;
const int mod=1e9+10;
ll a,b,x,y,n;
ll ac1()
{
    ll c=a,d=b,e=x,f=y,m=n;
    if((a-n)<x)
    {
        ll ch1=x-(a-n);
        m=m-ch1;
        c-=m;
        d=max(f,d-ch1);
        
    }
    else
    {
        c-=n;
    }
//    cout<<c<<"  "<<d<<endl;
    return c*d;
}
ll ac2()
{
    ll c=a,d=b,e=x,f=y,m=n;
    if((b-n)<y)
    {
        ll ch1=y-(b-n);
        m=m-ch1;
        d-=m;
        c=max(e,c-ch1);
        
    }
    else
    {
        d-=n;
    }
    return c*d;    

}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>a>>b>>x>>y>>n;
        if(a==x&&b==y)
        {
            cout<<a*b<<endl;continue;
        }
        if(a==x)
        {
            cout<<a*max(y,b-n)<<endl;continue;
        }
        if(b==y)
        {
            cout<<max(x,a-n)*b<<endl;continue;
        }
    //    cout<<ac1()<<"  "<<ac2()<<endl;
        cout<<min(ac1(),ac2())<<endl;
    }
}

C:http://codeforces.com/contest/1409/problem/C

题意:

构建出含n个数的等差数列,包含所给的x,y

要求max(a1,a2...an)最小

解析:

给出了x,y,那么要使得最大值最小,先假设y为最大。

x~y以及1~x之间的数尽量塞满,才能保证y之后尽量少放。

那么x~y之间的数字尽量密集。

由于是等差数列,根据am=a1+(m-1)*d,以x为首项,y为末项,枚举这个项数m,求出最小的间距d。(d<=n)

以这个间距d,打印x~y,1~x,y~  之间的数字即可。

#include<bits/stdc++.h>
#include<map>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=5e3+10;
const int maxn2=1e9+10;
const int mod=1e9+10;
ll a,b,x,y,n;
ll ac1()
{
    ll c=a,d=b,e=x,f=y,m=n;
    if((a-n)<x)
    {
        ll ch1=x-(a-n);
        m=m-ch1;
        c-=m;
        d=max(f,d-ch1);
        
    }
    else
    {
        c-=n;
    }
//    cout<<c<<"  "<<d<<endl;
    return c*d;
}
ll ac2()
{
    ll c=a,d=b,e=x,f=y,m=n;
    if((b-n)<y)
    {
        ll ch1=y-(b-n);
        m=m-ch1;
        d-=m;
        c=max(e,c-ch1);
        
    }
    else
    {
        d-=n;
    }
    return c*d;    

}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,x,y;
        cin>>n>>x>>y;
        int mind=mod;
        for(int i=2;i<=50;i++)  //i<=50,否则对于x=1,y=50,d枚举不到1
        {
            if((y-x)%(i-1)==0&&i<=n)
            {
                mind=min(mind,(y-x)/(i-1));
            }
        }
    //    cout<<mind<<"--"<<endl;
        int cnt=2;
        cout<<x<<" "<<y<<" ";
        ll md=x;
        while(1)
        {
            if(cnt==n)
                break;
            md+=mind;
            if(md<y)
            {
                cout<<md<<" ";
                cnt++;
            }
            else
                break;
        }
        md=x;
        while(1)
        {
            if(cnt==n)
                break;
            md-=mind;
            if(md<=0)
                break;
            else
            {
                cout<<md<<" ";
                cnt++;
            }
        }
        md=y;
        while(1)
        {
            if(cnt==n)
                break;
            md+=mind;
            cout<<md<<" ";
            cnt++;            
        }
        cout<<endl;
    }
}

D:http://codeforces.com/contest/1409/problem/D

题意:

给2个数n,s。问n最少要加几使n的各个位置的数相加小于等于s.

解析:

对于本身n就不满足条件的情况,各个位子上的数,必须要加到10,才能使sum变小。

所以从后往前,不断把<10的补到10即可,满足条件即终止。

#include<bits/stdc++.h>
#include<map>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=5e3+10;
const int maxn2=1e9+10;
const int mod=1e9+10;
ll a,b,x,y,n;
ll ac1()
{
    ll c=a,d=b,e=x,f=y,m=n;
    if((a-n)<x)
    {
        ll ch1=x-(a-n);
        m=m-ch1;
        c-=m;
        d=max(f,d-ch1);
        
    }
    else
    {
        c-=n;
    }
//    cout<<c<<"  "<<d<<endl;
    return c*d;
}
ll ac2()
{
    ll c=a,d=b,e=x,f=y,m=n;
    if((b-n)<y)
    {
        ll ch1=y-(b-n);
        m=m-ch1;
        d-=m;
        c=max(e,c-ch1);
        
    }
    else
    {
        d-=n;
    }
    return c*d;    

}
ll check(ll x)
{
    ll sum=0;
    while(x)
    {
        ll md=x%10;
        x/=10;
        sum+=md;
    }
    return sum;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ll n,s;
        cin>>n>>s;
        ll sum=check(n);
        if(sum<=s)
        {
            cout<<"0"<<endl;
            continue;
        }
        ll ans=0;
        ll md=1;
        for(int i=1;i<=18;i++)
        {
            ll y=(n/md)%10;
            ll yy=md*(10-y);
            n+=yy;
            ans+=yy;
            if(check(n)<=s)
            {
                break;
            }
            md*=10;
        }
        cout<<ans<<endl;
    }
}

E:http://codeforces.com/contest/1409/problem/E

题意:

有n个点给x,y坐标,有2个长为k的平台,点不断下落问最多能接住几个点。

解析:

由于平台可以放在无限往下的地方,所以这里的y就可以忽略。

对x进行从小到大的排序。

定义L[i],表示平台以i为右端点,所能容纳的最多点

定义R[i],表示平台以i为左端点,所能容纳的最多点

答案即为max(L[i],R[i+1])

#include<bits/stdc++.h>
#include<map>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int maxn2=1e9+10;
const int mod=1e9+10;
ll x[maxn];
ll r[maxn],l[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
//        memset(l,0,sizeof(l));
//        memset(r,0,sizeof(r));
        ll n,k;
        cin>>n>>k;
        for(int i=1;i<=n;i++)
            {
                cin>>x[i];
            }
        ll y;
        for(int i=1;i<=n;i++)
            cin>>y;
        sort(x+1,x+1+n);
        int j = n;
        r[j+1]=0;
        for(int i=n;i>=1;i--)
        {
            while(x[j]-x[i]>k)
                j--;    //可容纳x[i]~x[j]
            r[i]=j-i+1;
            r[i]=max(r[i],r[i+1]);  //保留i之后的最大容纳量
        }
        j=1;
        l[0]=0;
        for(int i=1;i<=n;i++)
        {
            while(x[i]-x[j]>k)
                j++;
            l[i]=i-j+1;
            l[i]=max(l[i],l[i-1]);
        }
        ll maxx=1;
        for(int i=1;i<=n;i++)
        {
            maxx=max(maxx,l[i]+r[i+1]);
        }
        cout<<maxx<<endl;
    }
}

 

posted @ 2020-09-05 23:34  liyexin  阅读(245)  评论(0编辑  收藏  举报