A.这道题我是用公式写的
首先介绍log函数
引入#include
以e为底:log(exp(n))
以10为底:log10(n)
以m为底:log(n)/log(m)
那么求10000阶乘我们只需要从log10(1)+........+log10(10000)向上取整即可,按照这个思路就很好写了,贴代码了
#include
using namespace std;
double c;
int x;
int main()
{
for(int i=1;;i++)
{
c+=log10(i);
if(c>=9999)
{
x=i;
break;
}
}
cout<
B.这道题开始想了很久,一直不知道怎么写,后来看到期望我就来一个一个的分析期望,最高的炮台明显期望是1,最低的是1/2019,那么来分析中间的期望,只考虑比当前炮台高的炮台,因为比当前炮台还矮的话无法对期望产生任何影响,比如考虑第四高的炮台,有三个炮台比他高,那么有四个位置,接下来要考虑4个位置是否等可能,我是这么想的,不一定对,可能性的大小是由炮台之间的炮台的个数决定的,又因为没有任何限制,所以每个位置的可能性都是相同的,那么结果就很好算了。
#include
using namespace std;
double c;
int main()
{
for(int i=1;i<=2019;i++)
c+=1.0/i;
printf("%.4lf",c);
return 0;
}
C.二进制枚举
有25个格子,所以用一个25的二进制数来枚举马的状况,并去逐一检查,看马是否占据了整个方格,上代码了
#include
using namespace std;
int dx[]={0,-1,0,1};
int dy[]={1,0,-1,0};
int x[]={-1,1,-2,-2,-1,1,2,2};
int y[]={2,2,-1,1,-2,-2,-1,1};
int n=5,m=5,q1;
bool vis[10][10],g[10][10];
int main()
{
int r=n*m;
int minx=r;
for(int s=0;s<1<>i&1)
{
g[i/m][i%m]=1;
vis[i/m][i%m]=1;
cnt++;
}
else
g[i/m][i%m]=0;
}
if(cnt>minx) continue;
ans=cnt;
for(int i=0;i<=4;i++)
for(int j=0;j<=4;j++)
{
if(g[i][j]==1)
for(int k=0;k<=3;k++)
{
int nx=i+dx[k];
int ny=j+dy[k];
if(g[nx][ny]==0&&nx>=0&&nx<=4&&ny>=0&&ny<=4)
for(int q=2*k;q<=2*k+1;q++)
{
int nx1=i+x[q];
int ny1=j+y[q];
if(!vis[nx1][ny1]&&nx1>=0&&nx1<=4&&ny1>=0&&ny1<=4)
{
vis[nx1][ny1]=1;
ans++;
}
}
}
}
if(ans==25&&cnt
D.这题的思路感觉技巧性太强,我这个笨脑子完全没想到。。。首先要保证图的连通性,并且权值之和要最小,最小生成树了,但一开始并没有想到这个生成可以直接算,权值之和最小的应该是0和其他所有的点都连一条边,这样也保证了图的连通性,因为x|y>=x,等于x的时候就是最小值了。每条边的权值都应该等于较大的那个点的编号,举个栗子,10号节点二进制为1010,那么可以和10号节点连边的点事二进制为这些的数(0010,0000,1000),那么每个节点可以连的边数是2^二进制中的1 -1条,然后把所有的数乘起来就算出来了,别忘了取模
#include
using namespace std;
const int MOD=1e9+7;
int sum[2100],t;
long long ans=1;
int main()
{
for(int i=1;i<=2018;i++)
{
t=0;
for(int j=0;i>>j>0;j++)
{
if(i>>j&1) t++;//统计1的个数
}
sum[i]=(1<
E.
欧拉函数,考查的是欧拉函数的计算,根据唯一分解定理,p=p1^a1+p2^a2+p3^a3+.......+pn^an,那么欧拉函数的值n(1-1/p1)*(1-1/p2)......*(1-1/pn)
因为res的初值为n,res=res*(1-1.0/i)即是答案
F.
这道题其实就是简单的几何问题,首先内切圆和外接圆的半径公式要知道,r内=2s/(a+b+c),r外=abc/4s,最开始判断三角形存在我用的是两边之和大于第三边,但是只有80分,后来想了想,还是精度的问题,比如精确到小数点后1位的时候,A=1.48,B=1.47,C=1.93,精确到小数点后一位A=1.4,B=1.4,C=1.9,前者可以构成三角形,而后者不能,所以出错了。还是用叉积来判断,叉积等于0,三角形不存在,用叉积避免了边长的误差,只有1次计算,更加精确,好了,上代码了。
#include
using namespace std;
double a,b,c,d,e,f,A,B,C,p,r,r1,s;
int t;
double length(double a,double b,double c,double d)
{
return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%lf %lf %lf %lf %lf %lf",&a,&b,&c,&d,&e,&f);
A=length(a,b,c,d);
B=length(a,b,e,f);
C=length(c,d,e,f);
s=fabs((a-c)*(f-d)-(e-c)*(b-d));
if(s==0)
{
cout<<"NO SOLUTION"<
G.简单贪心,分成前后两段,直接贪心就好
#include
using namespace std;
int n,a[500005],ans,cnt,x;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
cnt=1;
for(int i=1;i<=n/2;i++)
{
while(a[i]*2>a[x+cnt]&&x+cnt<=n) cnt++;
if(x+cnt>n) break;
ans++;
cnt++;
}
cout<
H.每个灯状态改变都是因为因数,所以最后灯是亮着还是熄灭取决于因数个数的奇偶性,但是一看数据范围10^18,有点蒙,看了讲解之后,才知道因数个数是奇数的数都是完全平方数,而完全平方数的和有公式n*(n+1)*(2*n+1)/6,然后在算的时候取一下模就行了。计算的时候也有技巧,因为除法不遵循同余,还要想办法把除六算出来,方法就是将6拆成2*3,t*(t+1)必然是2的倍数,直接除2就好,在判断t*(t+1)是不是3的倍数,ruguoshi,除以3,不是则可以说明2*t+1肯定是3的倍数,因为t和t+1都不是3的倍数,那么只能是t%3=1,(t+1)%3=2,所以2*t+1是3的倍数。
#include
using namespace std;
const long long mod=1e9+7;
long long ans,n;
int main()
{
scanf("%lld",&n);
long long t=sqrt(n);
ans=t*(t+1)/2;
if(ans%3==0)
ans=(ans/3)%mod*(2*t+1)%mod;
else
ans=(ans%mod*((2*t+1)/3)%mod)%mod;
cout<