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;
}
本文解析了五道算法题目,包括求最大偶数和、计算对角线上的点对数量、计算期望收益、比较数学表达式的值及求解特定余数的组合数。

2461

被折叠的 条评论
为什么被折叠?



