Codeforce 445(A,B,C,D,E)

来源:互联网 发布:淘宝网创立时间 编辑:程序博客网 时间:2024/05/05 06:27

A.链接:点击打开链接

题意:在一个N*M的棋盘上,'.'为可放棋的点,'-'为不放棋的点,有'B'和'W'两种棋,要求这两种棋不能相邻,输出满足条件的棋盘

代码:

<span style="font-size:18px;">#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>using namespace std;int main(){    int n,m,i,j,k;    char s[105][105];    while(scanf("%d%d",&n,&m)!=EOF){        memset(s,0,sizeof(s));                  //就是一个国际象棋的棋盘...        for(i=1;i<=n;i++)        for(j=1;j<=m;j++)        scanf(" %c",&s[i][j]);        for(i=1;i<=n;i++){            for(j=1;j<=m;j++){                if(s[i][j]=='.'){                    if(i%2){                        if(j%2)                        printf("B");                        else                        printf("W");                    }                    else{                        if(j%2)                        printf("W");                        else                        printf("B");                    }                }                else                printf("%c",s[i][j]);            }            printf("\n");        }    }    return 0; }</span>

 

B.链接:点击打开链接

题意:有n种药品,m种反应,反应可以翻倍,例如1,2反应,2,3反应,则当1在试管中时,将2放入试管种威力乘2,再将3放入试管中,威力则再乘2,初始威力为1,输出最后的威力

代码:

<span style="font-size:18px;">#include <queue>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;int par[105],r[105];int find(int x){    if(x==par[x])    return x;    return par[x]=find(par[x]);}void unite(int x,int y){    x=find(x);    y=find(y);    if(x==y)    return;    if(r[x]<r[y])    par[x]=y;    else{        par[y]=x;        if(r[x]==r[y])        r[x]++;    }}bool same(int x,int y){    return find(x)==find(y);}                                               //并查集模板int main(){    int i,j,n,m,a,b,ans,sum;    while(scanf("%d%d",&n,&m)!=EOF){        ans=0;        for(i=0;i<=n;i++){            par[i]=i;            r[i]=0;        }        while(m--){            scanf("%d%d",&a,&b);            unite(a,b);        }        sum=0;        for(i=1;i<=n;i++){        if(par[i]==i){        sum++;        }                                       //注意求的其实是联通数的个数        }        printf("%I64d\n",(long long)pow(2,n-sum));    }    return 0; }</span>


C.链接:点击打开链接

题意:有一个图,每个顶点有一个权值,每一条边有一个权值,求边的权值除以边两个顶点的权值的和的最大值

代码:

<span style="font-size:18px;">#include <queue>#include <vector>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;int num[505];int main(){    int n,m,i,j,a,b,c,p,q;    double s,ans;    while(scanf("%d%d",&n,&m)!=EOF){        for(i=1;i<=n;i++)        scanf("%d",&num[i]);        ans=0;        while(m--){            scanf("%d%d%d",&a,&b,&c);            ans=max(ans,(num[a]+num[b])*1.0/c);        }        printf("%.15lf\n",ans);    }    return 0; }</span>


D.链接:点击打开链接

题意:由题目给出的一段程序,随机给出数组a和数组b,根据下图公式输出数组c

代码:

<span style="font-size:18px;">#include <queue>#include <vector>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;long long n,d,x;long long a[500005],b[500005],c[500005];long long getNextX(){    x=(x*37+10007)%1000000007;    return x;}long long initAB(){    long long i;    for(i=0;i<n;i=i+1)    a[i]=i+1;    for(i=0;i<n;i=i+1)    swap(a[i],a[getNextX()%(i+1)]);    for(i=0;i<n;i=i+1){        if(i<d)        b[i]=1;        else        b[i]=0;    }    for(i=0;i<n;i=i+1)    swap(b[i],b[getNextX()%(i + 1)]);}int main(){    long long i,j,ans;    while(scanf("%I64d%I64d%I64d",&n,&d,&x)!=EOF){    initAB();    vector<long long> v;    for(i=0;i<n;i++)    if(b[i])    v.push_back(i);                             //因为数组b只能是0或1,因此b中1的个数决定了算出c的复杂度    if(v.size()<(long long)sqrt(n)){            //当b中1的个数较少时,可以直接输出c            for(i=0;i<n;i++){            ans=0;            for(j=0;j<v.size()&&v[j]<=i;j++)            ans=max(ans,a[i-v[j]]);            printf("%I64d\n",ans);        }    }    else{        for(i=0;i<=n;i++)        c[i]=n+1;        for(i=0;i<n;i++)        c[a[i]]=i;        for(i=0;i<n;i++){            for(j=n;j>0;j--){                   //记录每个值的位置,判断最近的数组b为1的位置                if(c[j]<=i&&b[i-c[j]]){                    printf("%I64d\n",j);                    break;                }            }            if(j==0)            puts("0");        }    }    }    return 0;}</span>


E.链接:点击打开链接

题意:给出n个数,初始为1~n,有m个操作,一种是将区间[l,r]内的值改为x,同时改点会累加一个|x-y|的值,第二种询问[l,r]区间内产生的累加值的和

代码:

#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>using namespace std;const long long SIZE=100005;                    //用两个标记,一个是懒惰标记,另一个是判断该节点表示的long long cnt[SIZE<<2],add[SIZE<<2],sum[SIZE<<2];                    void pushup(int rt){                            //区间是否是同一个值    sum[rt]=sum[rt<<1]+sum[rt<<1|1];    if(cnt[rt<<1]&&cnt[rt<<1]==cnt[rt<<1|1])    cnt[rt]=cnt[rt<<1];    else    cnt[rt]=0;}void pushdown(long long rt,long long m){    if(add[rt]){        add[rt<<1]+=add[rt];        add[rt<<1|1]+=add[rt];        sum[rt<<1]+=add[rt]*(m-(m>>1));        sum[rt<<1|1]+=add[rt]*(m>>1);        cnt[rt<<1]=cnt[rt<<1|1]=cnt[rt];        add[rt]=0;    }}void build(long long l,long long r,long long rt){    long long m;    add[rt]=sum[rt]=0;    if(l==r){        cnt[rt]=l;        return ;    }    m=(l+r)>>1;    build(l,m,rt<<1);    build(m+1,r,rt<<1|1);    pushup(rt);}void update(long long L,long long R,long long c,long long l,long long r,long long rt){    long long m;    if(L<=l&&r<=R&&cnt[rt]){                    //同一个值才更新        add[rt]+=abs(cnt[rt]-c);        sum[rt]+=abs(cnt[rt]-c)*(r-l+1);        //不是同一个值就无法直接懒惰标记更新        cnt[rt]=c;        return;    }    pushdown(rt,r-l+1);    m=(l+r)>>1;    if(L<=m)    update(L,R,c,l,m,rt<<1);    if(R>m)    update(L,R,c,m+1,r,rt<<1|1);    pushup(rt);}long long query(long long L,long long R,long long l,long long r,long long rt){    long long m,ans;    if(L<=l&&r<=R)    return sum[rt];    pushdown(rt,r-l+1);    ans=0;    m=(l+r)>>1;    if(L<=m)    ans+=query(L,R,l,m,rt<<1);    if(R>m)    ans+=query(L,R,m+1,r,rt<<1|1);    return ans;}                                               //线段树区间询问int main(){    long long n,m,i,j,a,b,c,ch,sign;    while(scanf("%I64d%I64d",&n,&m)!=EOF){        build(1,n,1);        while(m--){            scanf("%I64d",&ch);            if(ch==2){                scanf("%I64d%I64d",&a,&b);                printf("%I64d\n",query(a,b,1,n,1));            }            else{                scanf("%I64d%I64d%I64d",&a,&b,&c);                update(a,b,c,1,n,1);            }        }    }    return 0;}



 

0 0