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循环找公差了。