蓝桥杯刷题C-最短路、路径、特别数的和、等差数列(第十天12.24)

1、最短路:这道题看起来难,但是是因为是填空题,用看就能看出是六,到达s点就只有两条路,最短路就是6。代码就省了。

2、路径:这道题最关键的就是求最短路径,用Dijkstra算法就好了,然后每个数之间的长度需要去求,两数之间小于等于21的去求两个数的最小公倍数就好了。对了,这里求最小公倍数不能用暴力算法。

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define inf 10000000000
#define N 3000
#define n 2021
int a[N][N];
int gys(int i,int j)
{
	int k;
	k=i%j;
	while(k)
	{
		i=j;
		j=k;
		k=i%j;
	}
	return j;
}

void DJ()
{
	int dist[N],visit[N],i,j,k,min,c;
	for(i=1;i<=n;i++)
	{
		dist[i]=a[1][i];
	}
	for(i=1;i<=n;i++)
	{
		visit[i]=0;
	}
	for(i=1;i<=n;i++)//关键 
	{
		min=inf;
		for(j=1;j<=n;j++)
		{
			if(visit[j]==0&&dist[j]<min)
			{
				min=dist[j];
				k=j;
			}
		}
	     visit[k]=1;
	    for(c=1;c<=n;c++)
	    {
	    	if(a[k][c]<inf)
	    	{
	    	   if(dist[c]>dist[k]+a[k][c]) 
	    	   {
	    		  dist[c]=dist[k]+a[k][c];
			   }
		    }
		}
    }
	printf("%d",dist[n]);
}



int main()
{
	int i,j;
	for(i=1;i<n;i++)
	{
		for(j=1;j<=n;j++)
		{
			if(i==j)
			a[i][j]=0;
			else
			a[i][j]=inf;
		}
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
			if(i!=j&&abs(i-j)<=21)
			{
				a[i][j]=i*j/gys(i,j);
				a[j][i]=i*j/gys(i,j);
			}
		}
	}
	DJ();
	return 0; 
 } 

3、特别数的和:判断一个数中带不带特殊数字,如果1带就加上这个数,用个for循环,然后写一个把各个数拆开来的函数就好了。

#include <stdio.h>
#include <stdlib.h>

int ans(int a)
{
  int i,j;
  while(a)
  {
    i=a%10;
    a/=10;
    if(i==2||i==0||i==9||i==1)
    return 1;
  }
  return 0;
}


int main(int argc, char *argv[])
{
  // 请在此输入您的代码
  int n;
  scanf("%d",&n);
   int i,j;
   long long int sum=0;
   for(i=1;i<=n;i++)
   {
      if(ans(i))
      sum+=i;
   }
   printf("%lld",sum);
  return 0;
}

4、等差数列:思想很简单,就是找出最大最小值和两个数之间最小的公差。但是下面的代码只能得70分,因为用了两个for循环,运行超了。

#include <stdio.h>
#include <stdlib.h>
#include<math.h>

int main(int argc, char *argv[])
{
  // 请在此输入您的代码
  int n;
  scanf("%d",&n);
  int a[n];
  int i,j,max=0,min=100000010;
  for(i=0;i<n;i++)
  {
     scanf("%d",&a[i]);
      if(max<a[i])
         max=a[i];
      if(min>a[i])
         min=a[i];
  }
  int cz=abs(a[0]-a[1]);//差值
  for(i=0;i<n-1;i++)
  {
    for(j=i+1;j<n;j++)
    {
       if(abs(a[i]-a[j])<cz)
       cz=abs(a[i]-a[j]);
    }
  }
   printf("%d",(max-min)/cz+1);
  return 0;
}

我突然翻文章知道:公差d一定可以整除数列中每一个数ai减第一个数a1,即:(ai-a1)%d = 0,则公差d最大为(ai-a1)的最大公因数。那就可以不用两个for循环找公差了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值