Educational Codeforces Round 20解(bu)题记录

A. Maximal Binary Matrix

解法:暴力模拟+贪心

#include<bits/stdc++.h>
using namespace std;
int a[110][110];
int main(){
    int n,k,cmp,f=0;scanf("%d%d",&n,&k);
    if(k>n*n){puts("-1");return 0;}cmp=n;
    int r=1;
    while(k>=2*cmp-1){
        k-=2*cmp-1;cmp-=1;
        for(int i=1;i<=n;i++) a[r][i]=a[i][r]=1;
        r++;
        if(k==0) break;
    }
    if(k==0){
        for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
        }
        return 0;
    }
    if(k&1){
        a[r][r]=1;k-=1;
        k/=2;
        for(int i=r+1;i<=r+k;i++) a[r][i]=a[i][r]=1;
    }
    else{
        a[r+1][r+1]=a[r][r]=1;k-=2;k/=2;
        for(int i=r+1;i<=r+k;i++) a[r][i]=a[i][r]=1;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

B. Distances to Zero

解法:正着扫一遍,倒着扫一遍记录答案就好

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N],ans[N];
set<int>se;
int main(){
    int n;scanf("%d",&n);se.insert(1e8);
    for(int i=1;i<=n;i++) {scanf("%d",&a[i]);ans[i]=1e8;}
    int tmp=-1;
    for(int i=1;i<=n;i++){
        if(a[i]==0) tmp=i,ans[i]=0;
        else{
            if(tmp!=-1) ans[i]=i-tmp;
        }
    }
    tmp=-1;
    for(int i=n;i>=1;i--){
        if(a[i]==0) tmp=i,ans[i]=0;
        else{
            if(tmp!=-1) ans[i]=min(ans[i],tmp-i);
        }
    }
    for(int i=1;i<=n;i++) printf("%d ",ans[i]);
    return 0;
}

C. Maximal GCD

题意:构造n个数,使得他们的和为一个数,且gcd最大

解法:sqrt(n)处理最大gcd,构造 gcd*(1+2+...+n-1+k)   k=sum/gcd-(n-1)*n/2;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k;
ll max_(ll a,ll b) {return a>b?a:b;}
int main(){
    scanf("%I64d%I64d",&n,&k);
    if(k>=1e6){puts("-1");return 0;}
    int ans=-1;ll cmp=k*(k+1)/2;
    for(ll i=1;i*i<=n;i++){
        if(n%i) continue;
        if(n/i>=cmp) ans=max_(ans,i);
        if(i>=cmp) ans=max_(ans,n/i);
    }
    if(ans==-1){puts("-1");return 0;}
    ll cnt=n/ans;
    for(ll i=1;i<k;i++){
        printf("%I64d ",i*ans);
        cnt-=i;
    }
    printf("%I64d\n",cnt*ans);
    return 0;
}

D. Magazine Ad

解法:答案具有单调性,二分答案即可

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
char s[N];int a[N];int k,cnt;
bool ok(int x){
    int sum=0,res=0;
    for(int i=0;i<=cnt;i++){
        sum+=a[i];
        if(a[i]>x) return 0;
        if(sum>x){res++;sum=a[i];}
    }
    if(sum) res++;
    if(res>k) return 0;
    return 1;
}
int main(){
    scanf("%d",&k);getchar();gets(s);int p=0;
    for(int i=1;s[i];i++){
        if(s[i]==‘ ‘||s[i]==‘-‘) a[cnt++]=(i-p+1),p=i+1;
    }
    a[cnt]=strlen(s)-p;
    int l=1,r=N;int mid,ans=N;
    while(l<=r){
        mid=(l+r)>>1;
        //cout<<l<<" "<<r<<" "<<ans<<endl;
        if(ok(mid)) ans=min(ans,mid),r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

E. Roma and Poker

解法:考虑n^2的dp,dp[n][k]代表胜积分为k是否可行,然后最后dfs记录答案即可

#include<bits/stdc++.h>
using namespace std;
const int N=1100;
bool dp[N][2*N];
char ans[N];int n,k;string s;
void dfs(int x,int k){
    //cout<<x<<" "<<k<<endl;
    if(x==0) return;
    if(s[x]==‘L‘&&dp[x-1][k-1]) dfs(x-1,k-1);
    else if(s[x]==‘W‘&&dp[x-1][k+1]) dfs(x-1,k+1);
    else if(s[x]==‘D‘&&dp[x-1][k]) dfs(x-1,k);
    else{
        if(dp[x-1][k-1]) ans[x]=‘L‘,dfs(x-1,k-1);
        else if(dp[x-1][k+1]) ans[x]=‘W‘,dfs(x-1,k+1);
        else if(dp[x-1][k]) ans[x]=‘D‘,dfs(x-1,k);
    }
}
int main(){
    std::ios::sync_with_stdio(false);
    cin>>n>>k>>s;s=‘0‘+s;dp[0][k+1]=1;
    //k+1 ????0
    //1 ????-k
    //2*k+1 ????k
    for(int i=1;i<=n;i++){
        for(int j=1;j<=2*k+1;j++){
            if(s[i]==‘L‘) dp[i][j]=dp[i-1][j-1];
            else if(s[i]==‘W‘) dp[i][j]=dp[i-1][j+1];
            else if(s[i]==‘D‘) dp[i][j]=dp[i-1][j];
            else dp[i][j]=max({dp[i-1][j+1],dp[i-1][j-1],dp[i-1][j]});
            if(i!=n) dp[i][1]=0,dp[i][2*k+1]=0;
        }
    }
    if(!dp[n][2*k+1]&&!dp[n][1]) {puts("NO");return 0;}
    if(dp[n][2*k+1]){dfs(n,2*k+1);}
    else dfs(n,1);
    for(int i=1;i<=n;i++) if(s[i]!=‘?‘) ans[i]=s[i];
    for(int i=1;i<=n;i++) printf("%c",ans[i]);printf("\n");
    return 0;
}

F. Coprime Subsequences

题意:对于给定的序列,问有多少子序列的gcd为1

解法:考虑到题目的范围,即1e5的范围内约数大约有200,1e9的范围约数大约有800个,然后枚举gcd,从总答案里面减去就好,因为约数有容斥的地方,所以考虑用莫比乌斯反演,应用答案约数之间的关系可求解

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int mbs[N],vis[N],p[N];
const int mod=1e9+7;
ll pow_(int a,int b){
    ll res=1,tmp=a;
    while(b){
        if(b&1) (res*=tmp)%=mod;
        b/=2;
        (tmp*=tmp)%=mod;
    }
    return res;
}
void mobius(){
    mbs[1]=1;int cnt=0;
    for(int i=2;i<N;i++){
        if(!vis[i]) p[++cnt]=i,mbs[i]=-1;
        for(int j=1;j<=cnt&&i*p[j]<N;j++){
            vis[i*p[j]]=1;
            if(i%p[j]==0) {mbs[i*p[j]]=0;break;}
            mbs[i*p[j]]=-mbs[i];
        }
    }
}
int cnt[N],a[N];
int main(){
    int n;scanf("%d",&n);mobius();int m=0;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),m=max(m,a[i]);
    for(int i=1;i<=n;i++){
        for(int j=1;j*j<=a[i];j++){
            if(a[i]%j==0){cnt[j]++;if(a[i]!=j*j) cnt[a[i]/j]++;}
        }
    }
    ll ans=0;
    for(int i=1;i<=m;i++){
        ll tmp=((pow_(2,cnt[i])+mod-1)%mod*mbs[i]%mod+mod)%mod;
        (ans+=tmp)%=mod;
    }
    printf("%I64d\n",ans);
    return 0;
}

G. Periodic RMQ Problem

题意:有k个数,重复n次,组成的1e9的序列,区间修改+区间询问最小值

解法:ST表+线段树动态开点裸题

233

原文地址:https://www.cnblogs.com/vainglory/p/9735714.html

时间: 2024-09-29 15:23:58

Educational Codeforces Round 20解(bu)题记录的相关文章

codeforces round #499(div2) 做题记录

A. Stages 题意: 给你n个字母,你要选k个,你选择的相邻两个字母在字母表中必须满足中间至少隔一个字母,每个字母的权值是c-'a'+1,求最小权值和. k<=n<=50 题解:贪心,从前向后扫,满足题意的就加进去就可以了 1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 55 4 using namespace std; 5 int n,k; 6 char s[maxn]; 7 int w[max

Educational Codeforces Round 10 A B题、

A. Gabriel and Caterpillar 题意: 就是说  一个小孩子去观察毛毛虫从 h1的地方爬到h2的地方.毛毛虫从10点爬到22点.每小时爬的距离是a, 晚上22点到第二天早上10点 毛毛虫休息 每小时下落b距离.但是最初状态是那个小孩子从14点开始观察毛毛虫的, 必须过了24点才算一天 思路:模拟.但细节地方要注意 hint:但你要知道什么情况下永远也爬不上去,就是说每小时下落比每小时上升的距离大呢,但这还有个细节, 就是即使b>a 但毛毛虫是先可以爬10个小时,如果在这10

Educational Codeforces Round 20 C(math)

題目鏈接: http://codeforces.com/problemset/problem/803/C 題意: 給出兩個數n, k, 將n拆分成k個數的和,要求這k個數是嚴格遞增的,並且這k個數的gcd盡量大... 思路: 顯然題目的要求是求 n = a1*cnt + a2*cnt + a3*cnt..+ak*cnt 其中a1<a2<a3..<ak 並且要求cnt盡量大: 要使cnt盡量大,那麼顯然a1...ak要盡量小, 那麼可以令a1...ak=1, 2, 3, ..k, 令key

Educational Codeforces Round 20 B

Description You are given the array of integer numbers a0,?a1,?...,?an?-?1. For each element find the distance to the nearest zero (to the element which equals to zero). There is at least one zero element in the given array. Input The first line cont

Educational Codeforces Round 20 A

Description You are given matrix with n rows and n columns filled with zeroes. You should put k ones in it in such a way that the resulting matrix is symmetrical with respect to the main diagonal (the diagonal that goes from the top left to the botto

Educational Codeforces Round 20 D. Magazine Ad

The main city magazine offers its readers an opportunity to publish their ads. The format of the ad should be like this: There are space-separated non-empty words of lowercase and uppercase Latin letters. There are hyphen characters '-' in some words

Educational Codeforces Round 23 A-F 补题

A Treasure Hunt 注意负数和0的特殊处理.. 水题.. 然而又被Hack了 吗的智障 #include<bits/stdc++.h> using namespace std; int main() { int sa,sb,da,db,x,y; scanf("%d%d%d%d%d%d",&sa,&sb,&da,&db,&x,&y); sa=da-sa;sb=db-sb; if(sa<0)sa*=-1; if(

Educational Codeforces Round 20 C

Description You are given positive integer number n. You should create such strictly increasing sequence of k positive numbersa1,?a2,?...,?ak, that their sum is equal to n and greatest common divisor is maximal. Greatest common divisor of sequence is

Educational Codeforces Round 20 A. Maximal Binary Matrix(模拟)

题意:给你一个n*n的全是0的矩阵,和k个数字"1",让你把这k个数字1按照从上到下,从左到右的顺序构建出来 思路:模拟即可 代码: #include <iostream> #include <cstring> using namespace std; int main() { int n,k; int data[105][105]; while(cin>>n>>k) { memset(data,0,sizeof(data)); if(k