2019 ACM训练计划——( 每天5题 ) 训练计划18【循环数列 + 模拟】

A

Codeforces Round #273 (Div. 2), problem: © Table Decorations


题目大意

有红绿蓝三种颜色,然后要每张桌子上颜色不能完全相同,求满足这样条件的最大桌子数


题解

先对颜色数目进行从小到大排序,然后判断前两个较小的数目和是否大于颜色最多的那个,如果大于的话,那最大的桌子数就是三种颜色数量除以3的结果 反之,小于等于 采用贪心策略,最大的桌子数即为前两个较小的数量和 每次都是取最多的那个取两个 前面两个较小的取一个就好了

#include
using namespace std;
typedef long long ll;
ll a[5];
int main(){
    cin>>a[0]>>a[1]>>a[2];
    sort(a,a+3);
    if((a[0]+a[1])*2<=a[2])
        cout<<a[0]+a[1]<<endl;
    else
        cout<<(a[0]+a[1]+a[2])/3<<endl;
    return 0;
}

B

Codeforces Round #326 (Div. 2), problem: (B) Duff in Love


题目大意

给你一个数n 让你求他的除数中,不会被某个平方数整除的最大的那个数


题解

注意n的范围1e12 比较大,采用long long 来做

解题思路就是遇到一个除数,结果乘进去,然后只要n能被这个数除的话,就一直除下去,这也就是为了避免被某个平方数除的情况

#include
using namespace std;
typedef long long ll;
ll n;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    ll ans=1;
    for(int i=2;i<=sqrt(n);i++){
        if(n%i==0){
            ans*=i;
            while(n%i==0)
                n/=i;
        }
    }
    cout<<n*ans<<endl;
    return 0;
}

C

Codeforces Beta Round #2, problem: (A) Winner


题目大意

求最先到达最大m的那位玩家


题解

先统计每个玩家的最终点数,得出最多点数,再次模拟统计每个玩家最终点数的过程,最先达到最多点数,并且在最终点数也是最多点数的玩家胜利

#include
using namespace std;
const int maxn=1e3+10;
string name[maxn];
int ss[maxn],n;
map<string,int> mp,mm;
map<string,int>::iterator it;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    int remax=0;
    for(int i=0;i<n;i++){
        cin>>name[i]>>ss[i];
        mp[name[i]]+=ss[i];
        //remax=max(remax,mp[name[i]]);
    }
    for(it=mp.begin();it!=mp.end();it++)
        remax=max(remax,it->second);
    for(int i=0;i<n;i++){
        mm[name[i]]+=ss[i];
        if(mm[name[i]]>=remax&&mp[name[i]]==remax){
            cout<<name[i]<<endl;
            return 0;
        }
    }
    return 0;
}

D

Codeforces Round #257 (Div. 2), problem: (B) Jzzhu and Sequences


题目大意

数学公式化简 注意取模


题解

这个数列是循环数列,周期为6

既然知道周期为6 我们就可以进行预处理了,直接先算出来一个周期内的结果 然后对n 在一个周期内取余即可 不过注意n是从1开始的 我们需要对 ( n - 1) 周期取余

#include
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll x,y,n,a[10];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>x>>y;
    a[0]=x;
    a[1]=y;
    for(int i=1;i<=6;i++)
        a[i+1]=(a[i]-a[i-1])%mod;
    cin>>n;
    ll ans=(a[(n-1)%6]+mod)%mod;
    cout<<ans<<endl;
    return 0;
}

E

Codeforces Round #321 (Div. 2), problem: (B) Kefa and Company


题目大意

某个dalao有n个朋友,当朋友间的钱大于或者等于d时,就会感到贫穷。然后问最大的友谊值是多少


题解

此题是求某个区间范围内的数,并让该数对应的值和最大。可以采用先排序,然后遍历的做法,在遍历过程中统计出每个区间中的最大值,最后得到一个全局的最大值。

#include
using namespace std;
typedef long long ll;
ll n,d;
const int maxn=1e6+10;
struct node{
    ll mon,dd;
}stu[maxn];
int cmp(node x,node y){
    if(x.mon==y.mon)
        return x.dd<y.dd;
    return x.mon<y.mon;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>d;
    for(int i=0;i<n;i++)
        cin>>stu[i].mon>>stu[i].dd;
    sort(stu,stu+n,cmp);
    ll res=0,ans=0,k=0;
    for(int i=0;i<n;){
        if(stu[i].mon-stu[k].mon>=d){
            ans-=stu[k].dd;
            k++;
        }else{
            ans+=stu[i].dd;
            i++;
        }
        res=max(res,ans);
    }
    cout<<res<<endl;
    return 0;
}
学如逆水行舟,不进则退

你可能感兴趣的:(Codeforces✍)