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

A.链接:点击打开链接

题意:在n个数中取一些数加和,使之为偶数的最大值是多少

代码:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
long long a[100005],b[100005];
int main() {
    long long n,i,j,k,ans,sum;
    while(scanf("%I64d",&n)!=EOF){
        sum=k=0;
        for(i=0;i<n;i++){
        scanf("%I64d",&a[i]);
        if(a[i]%2==0)
        sum+=a[i];
        else
        b[k++]=a[i];
        }                                       //因为奇数加奇数是偶数,因此奇数个数是偶数时
//        cout<<k<<endl;                        //就全加上,否则去掉最小的奇数
        if(k%2==0)
        for(i=0;i<k;i++)
        sum+=b[i];
        else{
            sort(b,b+k);
            for(i=1;i<k;i++)
            sum+=b[i];
        }
        printf("%I64d\n",sum);
    }
    return 0;
}


B.链接:点击打开链接

题意:在一个1000*1000的网格上有n个点,问共用网格上格的对角线的点的对数

代码:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
long long a[5005],b[5005];
int main(){
    long long i,j,n,p,q,ans;
    while(scanf("%I64d",&n)!=EOF){
        ans=0;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(i=0;i<n;i++){
        scanf("%I64d%I64d",&p,&q);
        a[p+q]++;
        b[p-q+1000]++;
        }                                       //两个方向的所有对角线上的点的个数
        for(i=1;i<2000;i++){
        if(a[i]>1)                              //如果对角线上的点的个数超过一个就加一个C(n,2)
        ans+=(a[i]*(a[i]-1)/2);
        if(b[i]>1)
        ans+=(b[i]*(b[i]-1)/2);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


C.链接:点击打开链接

题意:有n个人围城一圈,每个人有一个区间,相邻的两个人每个人从区间任意挑一个数,如果两个人的数的乘积是p的倍数,则给两个人每人1000,问最后所有人钱的和的期望是多少

代码:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
long long l[100005],r[100005];
double x[100005];
int main() {
    long long n,p,i,j,tmp;
    double ans;
    while(scanf("%I64d%I64d",&n,&p)!=EOF){
        memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));
        memset(x,0,sizeof(x));
        for(i=0;i<n;i++){
        scanf("%I64d%I64d",&l[i],&r[i]);
        tmp=r[i]/p-(l[i]-1)/p;                  //求出区间内p的倍数的个数
        x[i]=1-((tmp*1.0)/(r[i]-l[i]+1));       //用的是不是p的倍数的概率
        }
        ans=(1-x[0]*x[n-1])*2000;               //求首和尾的钱数
        if(n>2)
        for(i=1;i<n;i++)
        ans+=((1-x[i]*x[i-1])*2000);
        printf("%.7lf\n",ans);
    }
    return 0;
}


D.链接:点击打开链接

题意:给出x,y,z的值和12个关于xyz的表达式,输出值最大的表达式,值相等则输出编号靠前的

代码:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
long double x,y,z;
struct node{
    long double sum;
    int id;
    friend bool operator<(node a,node b){
        if(a.sum==b.sum)
        return a.id<b.id;
        return a.sum>b.sum;
    }                                           //按大小排序,大小相同按序号排序
};
node s[20];
int main() {
    int i;
    while(cin>>x>>y>>z){
        for(i=0;i<12;i++)
        s[i].id=i+1;
        s[0].sum=pow(y,z)*log2(x);
        s[1].sum=pow(z,y)*log2(x);
        s[2].sum=y*z*log2(x);
        s[3].sum=y*z*log2(x);
        s[4].sum=pow(x,z)*log2(y);
        s[5].sum=pow(z,x)*log2(y);
        s[6].sum=x*z*log2(y);
        s[7].sum=x*z*log2(y);
        s[8].sum=pow(x,y)*log2(z);
        s[9].sum=pow(y,x)*log2(z);
        s[10].sum=x*y*log2(z);
        s[11].sum=x*y*log2(z);
        sort(s,s+12);                           //很明显每个表达式都可能会很大因此取对数
        if(s[0].id==1)                          //用long double否则精度不够,切记不要取两
        puts("x^y^z");                          //会对数,否则会造成某些数值特别小,返回一
        if(s[0].id==2)                          //个non
        puts("x^z^y");
        if(s[0].id==3)
        puts("(x^y)^z");
        if(s[0].id==4)
        puts("(x^z)^y");
        if(s[0].id==5)
        puts("y^x^z");
        if(s[0].id==6)
        puts("y^z^x");
        if(s[0].id==7)
        puts("(y^x)^z");
        if(s[0].id==8)
        puts("(y^z)^x");
        if(s[0].id==9)
        puts("z^x^y");
        if(s[0].id==10)
        puts("z^y^x");
        if(s[0].id==11)
        puts("(z^x)^y");
        if(s[0].id==12)
        puts("(z^y)^x");
    }
    return 0;
}


E.链接:点击打开链接

题意:有b个集合,每个集合含有相同的n个数,每个集合中取一个数使得最后modx==k,求满足条件的种数mod109 + 7

代码:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <cstring>
using namespace std;
long long MAX,Mod;
struct node{
    long long m[105][105];
};
node mul(node a,node b){
     long long i,j,k;
     node c;
     memset(c.m,0,sizeof(c.m));
     for(i=0;i<MAX;i++){
        for(j=0;j<MAX;j++){
            for(k=0;k<MAX;k++)
            c.m[i][j]+=(a.m[i][k]*b.m[k][j])%Mod;
            c.m[i][j]%=Mod;
        }
    }
    return c;
}
node P,I;
node quickpow(long long n){
    node m=P,b=I;
    while(n){
        if(n&1)
        b=mul(b,m);
        m=mul(m,m);
        n>>=1;
    }
    return b;
}                                               //矩阵快速幂的模板
int main(){
    long long i,j,n,b,k,x,num;
    long long s[15];
    node ans;
    while(scanf("%I64d%I64d%I64d%I64d",&n,&b,&k,&x)!=EOF){
        MAX=x,Mod=1000000007;
        memset(s,0,sizeof(s));
        memset(P.m,0,sizeof(P.m));              //p.m[i][j]代表的是从i变到i*10+j)%x的方法数
        for(i=0;i<n;i++){                       //问的是在b个相同的集合中,每个集合取一个数
            scanf("%I64d",&num);                //使得modx==k,因此p.m[i][j]其实相当于一个图
            s[num]++;                           //的邻接矩阵,因此问题变为从0这个点到k这个点
        }                                       //走k步的路径有几种,因此直接矩阵快速幂求解
        for(i=0;i<x;i++)
        for(j=0;j<x;j++)
        I.m[i][j]=(i==j);
        for(i=0;i<x;i++)
        for(j=1;j<=9;j++)
        P.m[i][(i*10+j)%x]+=s[j];               //预处理出图的临街矩阵
        ans=quickpow(b);
        printf("%I64d\n",ans.m[0][k]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值