2019蓝桥杯省赛A组模拟赛(1)

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<

 

你可能感兴趣的:(蓝桥杯)