[Updating] Educational Codeforces Round 20 解题报告

Problem A - Maximal Binary Matrix

简单构造就行了

//Author: Lixiang
#include<stdio.h>
const int maxn=101;
struct A{
    int a[maxn][maxn];
    int N,K;
    void init(){
        scanf("%d%d",&N,&K);
    }
    void work(){
        if(K>N*N){
            puts("-1");
            return ;
        }
        //int nx=1,ny=1;
        for(int i=1;K>0&&i<=N;i++){
            a[i][i]=1;
            K--;
            int nx=i,ny=i+1;
            while(K>1&&ny<=N){
                a[nx][ny]=a[ny][nx]=1;
                ny++;
                K-=2;
            }
        }
        for(int i=1;i<=N;i++){
            for(int j=1;j<N;j++)
                printf("%d ",a[i][j]);
            printf("%d\n",a[i][N]);
        }
    }
}sol;
int main(){
    sol.init();
    sol.work();
    return 0;
}

Problem B - Distances to Zero

求与最近的0的距离
正着扫一遍,反着扫一遍就行了

//Author: Lixiang
#include<stdio.h>
const int maxn=200001;
template <class T>
T min(T a,T b){
    return a<b?a:b;
}
struct B{
    int a[maxn],left[maxn],right[maxn],N;
    void init(){
        scanf("%d",&N);
        for(int i=1;i<=N;i++)
            scanf("%d",a+i);
    }
    void work(){
        int last=-N;
        for(int i=1;i<=N;i++){
            if(a[i]==0)last=i;
            left[i]=i-last;
        }
        last=2*N+1;
        for(int i=N;i>=1;i--){
            if(a[i]==0)last=i;
            right[i]=last-i;
        }
        for(int i=1;i<=N;i++)
            printf("%d ",min(left[i],right[i]));
    }
}sol;
int main(){
    sol.init();
    sol.work();
    return 0;
}

Problem C - Maximal GCD

从大到小检查是否存在N的因数f满足

f×i=1K1i<N

存在则输出
f2f3f(K1)fNf×i=1K1i

//Author: Lixiang
#include<stdio.h>
#include<stack>
#include<math.h>
using namespace std;
struct C{
    stack <int> S;
    long long N,K;
    void init(){
        scanf("%I64d%I64d",&N,&K);
    }
    bool check(long long n){
        n=N/n;
        return n*2>=K*(K+1);
    }
    void print(long long n){
        for(int i=1;i<K;i++){
            printf("%I64d ",i*n);
            N-=i*n;
        }
        printf("%I64d\n",N);
    }
    void work(){
        if(K>1e6||N*2<K*(K+1)){
            puts("-1");
            return;
        }
        int lim=sqrt(N);
        for(int i=1;i<=lim;i++){
            if(N%i!=0)continue;
            S.push(i);
            if(check(N/i)){
                print(N/i);
                return ;
            }
        }
        while(!S.empty()){
            if(check(S.top())){
                print(S.top());
                return ;
            }
            S.pop();
        }
        puts("-1");
    }
}sol;
int main(){
    sol.init();
    sol.work();
    return 0;
}

Problem D - Magazine Ad

自己的代码还在WA, 没时间改了,贴个别人代码

#include<cstdio>
char c;
int i,j,s,n,k,L=1,R,m,a[500000];
int main()
{
    scanf("%d\n",&k);
    for(;~(c=getchar());++R)
        if(++a[n],c==32||c==45)++n;
    for(--a[n];L<R;)
    {
        m=L+R>>1;
        for(i=j=s=0;i<=n&&j<k;++i)
            if(a[i]>m)j=k;else
            if((s+=a[i])>m)++j,s=a[i];
        if(j<k)R=m;else L=m+1;
    }
    printf("%d",L);
}

Problem F - Coprime Subsequences

//Author: Lixiang
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
const int MOD=1000000007;
const int maxn=100001;
long long mod(long long a){
    return a<MOD?a:a-MOD;
}
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
struct F{
    int Q[maxn];
    long long st[maxn],ans;
    int P[maxn],pcnt;
    int a[maxn],N;
    char isprime[maxn+1];
    void getprime(){
        P[++pcnt]=2;
        for(int i=3;i<maxn;i+=2){
            isprime[i+1]=1;
            if(isprime[i])continue;
            P[++pcnt]=i;
            if(i>400)continue;
            for(int j=i*i;j<maxn;j+=i)
                isprime[j]=1;
        }
    }
    void init(){
        getprime();
        scanf("%d",&N);
        st[0]=1;
        for(int i=1;i<=N;i++){
            scanf("%d",a+i);
            st[i]=mod(st[i-1]+st[i-1]);
        }
    }
    /*void dfs(int id,int g){
        if(g==1){
            ans=mod(ans+st[N-id]);
            return ;
        }
        for(int i=id+1;i<=N;i++)
            dfs(i,gcd(g,a[i]));
    }*/
    void work(){
        ans=st[N]-1;
        for(int i=1;i<=N;i++){
            int lim=sqrt(a[i]);
            for(int j=1;j<=lim;j++)
                if(a[i]%j==0){
                    Q[j]++;
                    Q[a[i]/j]++;
                }
            if(lim*lim==a[i])Q[lim]--;
            //dfs(i,a[i]);
        }
        for(int i=2;i<=100000;i++){
            if(isprime[i]==0){
                ans=mod(ans-st[Q[i]]+1+MOD);
                continue;
            }
            int ii=i,cnt=0,iii=1;
            while(ii>1){
                while(iii<=pcnt&&ii>=P[iii]&&ii%P[iii]!=0)iii++;
                if(ii%P[iii]!=0)break;
                ii/=P[iii];
                if(ii%P[iii]==0)break;
                cnt++;
            }
            if(ii!=1)continue;
            ans=(ans+(cnt%2==0?1:-1)*(st[Q[i]]-1))%MOD;
        }
        printf("%I64d\n",ans);
    }
}sol;
int main(){
    sol.init();
    sol.work();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值