2017-2018 ACM-ICPC Asia East Continent League Final (ECL-Final 2017) 个人题解

题面:https://codeforces.com/gym/101775

  • A. Chat Group

此题的题意很简单:就是给一个N和K让你计算(C(N,K)+C(N,K+1),+C(N,K+2)+...+C(N,N-1)+C(N,N))%1e9+7. 一种思路是写一个C(N,K)的函数,从K一直遍历到N一个一个计算,共1e5次,

而每次计算又需要1e5次循环,所以时间复杂度为1e10,肯定会超时。还好我队友聪明,提供了一个公式,能够根据C(N,K)再乘上一个系数计算出C(N,K+1).很牛逼。

这个公式为:C(N,K)*(N-K)/(K+1) = C(N,K+1)

所以:我们可以得出一个结论:要计算的答案 = (2N - (C(N,0)+C(N,1)+....+C(N,K-1)))%1e9+7, 

2可以用快速幂计算出来

(C(N,0)+C(N,1)+....+C(N,K-1)) 可以用公式递推,而公式中的除法需要改成乘以逆元,而1e9+7是一个质数就可以用费马小定理来求逆元,也就是用快速幂求逆元 = ksm(a,P-2)

#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
const ll mod = 1000000007;

int T;
ll N,K;

ll ksm(ll a,ll b){
    ll res = 1;
    while(b){
        if(b&1) res = res*a%mod;
        a = a*a%mod;
        b>>=1;
    }
    return res;
}

ll solve(){
    ll pre = 1,ck = 1;
    for(ll k = 0;k<=K-2;k++){
        ck = ck*(N-k)%mod*ksm(k+1,mod-2)%mod;
        pre = (pre+ck)%mod;
    }
    return (ksm(2,N)-pre+mod)%mod;
}

int main(){
    cin>>T;
    int kase = 0;
    while(T--){
        cin>>N>>K;
        printf("Case #%d: %lld
",++kase,solve());
    }
    return 0;
}
  •  C. Traffic Light

这题比赛时没有想出来,是一道构造思维题。当等待过一个红灯过后,可以控制偏移量让之后过红绿灯的时候都是绿灯。说实话到现在还没怎么懂,再问问其他人再来补题解

#include <iostream>
using namespace std;
const int maxn = 1e6+10;

int T,N;
int tmp1,tmp2;
int main(){
    cin>>T;
    int kase = 0;
    while(T--){
        cin>>N;
        int length = 0,mx = 0;
        for(int i = 0;i<N+1;i++) scanf("%d",&tmp1),length += tmp1;
        for(int i = 0;i<N;i++){
            scanf("%d%d",&tmp1,&tmp2);
            mx = max(mx,tmp2);
        }
        printf("Case #%d: %.6f
",++kase,(double)(length+mx));
    }


    return 0;
}
  • J. Straight Master
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;

int T,N;
int a[maxn],b[maxn];//原数组,差分数组

bool judge(){
    ll sum = 0;
    for(int i = 1;i<=N+1;i++){
        if(b[i]>0) sum+=b[i];
        if(i+3<=N+1 && b[i+3]<0) sum += b[i+3];
        if(sum<0) return false;
    }
    return sum == 0;
}
int main(){
    cin>>T;
    int kase = 0;
    while(T--){
        memset(a,0,sizeof a);memset(b,0,sizeof b);
        cin>>N;
        for(int i = 1;i<=N;i++) scanf("%d",&a[i]);
        for(int i = 1;i<=N+1;i++) b[i] = a[i]-a[i-1];
        if(judge()) printf("Case #%d: Yes
",++kase);
        else printf("Case #%d: No
",++kase);
    }

    return 0;
}
  • K. Downgrade
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
const ll mod = 1000000007;

ll T,A,B,N;
int a[maxn];
ll pre[maxn];

int main(){
    cin>>T;
    int kase = 0;
    while(T--){
        cin>>A>>B>>N;
        for(int i = 1;i<=A;i++) scanf("%d",&a[i]);
        for(int i = 1;i<=A;i++) pre[i] = pre[i-1]+a[i];
        int total = A;
        while(N--){
            int t = lower_bound(pre+1,pre+1+total,A)-pre;
            B = A-pre[t-1];
            if(A == t) break;
            A = t;
        }
        printf("Case #%d: %lld-%lld
",++kase,A,B);
    }
    return 0;
}
  • L. SOS
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
const ll mod = 1000000007;

int T,N;

int main(){
    cin>>T;
    int kase = 0;
    while(T--){
        printf("Case #%d: ",++kase);
        cin>>N;
        if(N<7) puts("Draw");
        else if(N%2 == 1) puts("Panda");
        else if(N%2 == 0 && N>=16) puts("Sheep");
        else puts("Draw");
    }
    return 0;
}
  •  M. World Cup
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
const ll mod = 1000000007;

int T,Q,x;
int money[10],p[100];

void init(){
    for(int i = 1;i<=48;i++) p[i] = money[1];
    for(int i = 49;i<=56;i++) p[i] = money[2];
    for(int i = 57;i<=60;i++) p[i] = money[3];
    for(int i = 61;i<=62;i++) p[i] = money[4];
    for(int i = 63;i<=63;i++) p[i] = money[5];
}


int main(){
    cin>>T;
    int kase = 0;
    while(T--){
        for(int i = 1;i<=5;i++) cin>>money[i];
        init();
        cin>>Q;
        ll y = 0;
        while(Q--){
            scanf("%d",&x);
            y += p[x];
        }
        printf("Case #%d: %lld
",++kase,y*10000);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/bigbrox/p/11622966.html