Educational Codeforces Round 77 (Div. 2) / contest 1260


题目地址:https://codeforces.com/contest/1260



A Heating

题意

思路

代码

int main()
{
    //freopen("input.txt","r",stdin);
    int n=read();
    REP(i,1,n)
    {
        int c=read(),s=read();
        int k=s/c;
        printf("%d\n",(s%c)*(k+1)*(k+1)+(c-s%c)*k*k);
    }

    return 0;
}



B Obtain Two Zeros

题意:给你两个数正整数a,b,每次可以选择一个正整数x,使得其中一个减去x,另外一个减去2x,问能否同时让两个数变为0。

思路:假设 a<b,如果 b>2*a 显然不行,否则我们可以同时把两个数变成 a-(b-a)。注意到不论 x 取什么值,我们都可以把这样的操作变成多次 -1 和 -2 的操作,所以我们只用想怎样的两个相同的数可以这样同时变为0,很容易发现是当 (a-(b-a))%3==0 时成立。

代码

int main()
{
    //freopen("input.txt","r",stdin);
    int t=read();
    while(t--)
    {
        int a=read(),b=read();
        if(a>b) swap(a,b);
        if(b>a*2) {puts("NO"); continue;}
        a-=b-a;
        puts(a%3==0?"YES":"NO");
    }

    return 0;
}



C Infinite Fence

题意:给定两个数 r 和 b,对于任意 x>=0,如果 x%r==0 则在 x 处涂上红色,如果 x%b == 0 则涂上蓝色,如果同时满足则任意涂一种颜色,问是否满足如下条件:把所有涂色的格点的坐标取出来从小到大排列,最长的连续相同的色块的长度小于k。

思路:首先如果把 r 和 b 同时除以 gcd(r, b) ,可以发现涂色的相对位置是一样的,其次对于 x%r == 0 && x%b == 0 的格点优先涂大的那个数,因为小的本身涂的格点就会多一些。假设 r<b,如果 b%r == 0,可以发现最长的 L=b/r-1;如果 b%r == 1,最长的 L=b/r;否则,最长的 L=b/r+1。然后用 L 和 k 比较即可。

代码

int main()
{
    //freopen("input.txt","r",stdin);
    int t=read();
    while(t--)
    {
        LL r=read(),b=read(),k=read();
        LL q=__gcd(r,b);
        r/=q; b/=q;
        if(r>b) swap(r,b);
        LL v=b/r;
        if(b%r>1) v++;
        else if(b%r==0) v--;
        puts(v<k?"OBEY":"REBEL");
    }

    return 0;
}



D A Game with Traps

题意:一条一维道路上有k个陷阱,每个陷阱由三元组(l, r, d)表示,l 代表陷阱位置,r 代表拆除陷阱位置(l<=r),d代表陷阱的厉害值。你有 m 个士兵,每个士兵有一个敏捷度 a[i],当一个士兵踩到陷阱(可无限使用)且敏捷度小于陷阱的厉害值时,士兵就会死去。你可以自己行动,也可以带着士兵行动(士兵不能自己行动),每走一格花费1单位时间。问最多能带多少个士兵,使得在时间 t (t>n) 内将所有士兵从 0 送到 n+1 处。

思路:首先这可以转换为求一个最小的敏捷度 amin,使得不管带上多少个敏捷度大于等于 amin 的士兵都可以按时到达,这显然是二分的思路。然后对于某个特定的敏捷度,我们只用考虑所有厉害值大于该敏捷度的陷阱。

假设只有一个陷阱,那么显然策略应该是:带着士兵走到 l-1 处,自己走到 r 处,走回 l-1,带着士兵走到 r,带着士兵走到 n+1;

假设有两个陷阱,那么分两种情况:陷阱互不交叉(l>rr || ll>r) 和陷阱相互交叉。简单画个图随便举个例子就可以发现,对于互不交叉的情况下,按照一个陷阱来处理两次是最优的;对于相互交叉的情况,取 lmin 和 rmax 作为一个“更大的陷阱”,然后按照一个陷阱来处理是最优的(也即一次性拆除多个陷阱,省去了交叉那一部分的路程)。

多个陷阱同理,把所有陷阱按照 l 从小到大排列,然后处理出多个组,其中组内的陷阱至少和组内另一个交叉,组与组之间的互不交叉。对每个组按照一个陷阱的策略处理即可。

(这道题的官方题解思路更好一点:本来要走 n+1,然后如果某个点属于至少一个 [ l i , r i ] [l_i,r_i] ,则这个点还会被走两次。)

代码

const int maxn=2e5+5;
int m,n,k,t,a[maxn],l[maxn],r[maxn],d[maxn];
struct node {int l,r,d;} ns[maxn];

bool cmp(node x,node y) {return x.l<y.l;}

bool can(int aa)
{
    int tot=0;
    REP(i,1,k) if(d[i]>aa) ns[tot++]=(node){l[i],r[i],d[i]};
    if(!tot) return 1;
    sort(ns,ns+tot,cmp);
    int ans=ns[0].l-1,i=1,maxr=ns[0].r,nowl=ns[0].l-1;
    while(i<tot)
    {
        if(ns[i].l>maxr)
        {
            ans+=3*(maxr-nowl)+(ns[i].l-1-maxr);
            nowl=ns[i].l-1;
            maxr=ns[i].r;
        }
        else maxr=max(maxr,ns[i].r);
        i++;
    }
    ans+=3*(maxr-nowl)+(n+1-maxr);
    return ans<=t;
}

int main()
{
    //freopen("input.txt","r",stdin);
    m=read(),n=read(),k=read(),t=read();
    REP(i,1,m) a[i]=read();
    REP(i,1,k) l[i]=read(),r[i]=read(),d[i]=read();
    int l=-1,r=maxn,mid;
    while(l<r-1)
    {
        mid=(l+r)>>1;
        if(can(mid)) r=mid;
        else l=mid;
    }
    int ans=0;
    REP(i,1,m) if(a[i]>=r) ans++;
    cout<<ans;

    return 0;
}



E Tournament

题意:有n个拳击手(n为2的幂)能力值分别为1-n,其中某个是你的朋友。贿赂一个拳击手需要a[i]元,你可以自行安排比赛顺序。问最少花多少钱可以使你的朋友获胜。

思路:假设朋友能力值最大,那么不用花钱,否则一定要花钱贿赂能力值最大的那个人,然后除了决赛之外,朋友和最牛那个人一定要分别在各自的 n/2 个人中获胜;然后一直往下思考。我们假设朋友所处的能力值区间为 [ 2 k , 2 k + 1 ) [2^k,2^{k+1}) ,设 n = 2 b n=2^b ,那么从高到低朋友要贿赂 2 b 2^b ,(除已经贿赂的) [ 2 b 1 , ) [2^{b-1},) 中最便宜的,(除已经贿赂的) [ 2 b 2 , ) [2^{b-2},) 中最便宜的…(除已经贿赂的) [ 2 k + 1 , ) [2^{k+1},) 中最便宜的,其中从前往后分别是它每一场比赛要对决的人所在的区间。

代码

const int maxn=2e6+5;
int n,a[maxn];
priority_queue<int,vector<int>,greater<int> > Q;

int main()
{
    //freopen("input.txt","r",stdin);
    n=read();
    REP(i,1,n) a[i]=read();
    LL ans=0;
    for(int i=n;~a[i];i--)
    {
        Q.push(a[i]);
        if(!(i&(i-1))) ans+=Q.top(),Q.pop();
    }
    cout<<ans;

    return 0;
}



F Colored Tree

题意

思路

代码


猜你喜欢

转载自blog.csdn.net/dragonylee/article/details/106146201