蓝桥杯

枯木逢春不在茂,年少且惜镜边人

这周5 1 假期 ,就在假期前 林木木 给我发了几道题 , 那么这周就好好看看这几道题吧,giao en~~~ 一giao我累个giaogiao!giao

首先看看第一题

在这里插入图片描述

#include<stdio.h>
 

int main()
{
    int n,a,b,c,ans=0;
    scanf("%d",&n);
    scanf("%d %d %d",&a,&b,&c);
    for(int i=1;i<=n;i++)
	{
        if(i%a!=0&&i%b!=0&&i%c!=0)
		ans++;
    }
    printf("%d",ans);
    return 0;
}

很简单的一道题,取余就行。
在这里插入图片描述2.
在这里插入图片描述

#include<stdio.h>
#include<string.h>
int main()
{
	int i;
    char a[1000];

    gets(a);

    for(int i=0;i<strlen(a);i++){

        if(a[i]<120) 
		a[i]=a[i]+3;
        else 
		a[i]=a[i]-23;
        printf("%c",a[i]);
    }

    return 0;

}

a-z 的阿斯扣码 97-122 所以 119 就 判断停止
在这里插入图片描述
3.在这里插入图片描述
这道题是螺旋矩阵,面试题考过,以前也学过,不过时间长了我又忘记的差不多了,现在来肝肝吧!

#include <stdio.h>
int a[1005][1005];
int main()
 {
    int n,m,h,k;
    int sum;
    int i=0,j=0,ans=1;
    a[i][j]=1;
    scanf("%d %d",&n,&m); 
    scanf("%d %d",&h,&k);
    sum=m*n;
    while(ans<sum)
    {
        while(j+1<m&&!a[i][j+1])
            a[i][++j]=++ans;
        while(i+1<n&&!a[i+1][j])
            a[++i][j] = ++ans;
        while(j-1>=0&&!a[i][j-1])
            a[i][--j] = ++ans;
        while(i-1>=0&&!a[i-1][j])
            a[--i][j] = ++ans;
    }
    printf("%d",a[h-1][k-1]);
    return 0;
}
 

依次进行右下左上的操作,就ok了,这个挺简便的
在这里插入图片描述
在这里插入图片描述
这道题有点难上网去学了学

#include<stdio.h>
int dp[1004][1004];
int main()
{
	int i,j;
	int ans=0;
	int m,n;
	cin>>m>>n;
	for(i=1; i<=n; i++)
	{ 
		dp[1][i]=n-i+1; 
	}
	for(i=2;i<=m;i++)
	{
		if(i&1)
		{
			for(j=n;j>=1;j--)
			{
				dp[i][j]=(dp[i-1][j-1]+dp[i][j+1])%10000; 
			}
		}
		else
		{
			for(j=1;j<=n;j++)
			{
				dp[i][j]=dp[i-1][j+1]+dp[i][j-1]; 
			} 
		}
	}
	ans = m & 1 ? dp[m][1] : dp[m][n]; 
	printf("%d",ans);
	return 0;
} 

这道题dp我实在是想不出来,所以大概介绍下dp

大家看看就行
详细请看 大佬

但是这里说说dp含义
dp【i】【j】表示第i个数取j的时候他有多少种方案

而且说说 i&1判断奇数的思路

比如 2
1 0
& 0 1
——————
0 0
而 3
1 1
& 0 1
——————
0 1
这样应该可以看懂了吧

现在说说奇数
也就是

if(i&1)
		{
			for(j=n;j>=1;j--)
			{
				dp[i][j]=(dp[i-1][j-1]+dp[i][j+1])%10000; 
			}

可以看到j从n 开始是的就是为了保证最大

下面看看(奇数)
上一行i-1偶数行中选择小于j(即小于等于j-1)的方案 与 最末尾最大的数j组合的方案数(即 dp[i-1][j-1]) + dp[i][j+1] (此时dp[i][j+1]=0 ,因为j=n,j+1不在1~n范围,所以为零

偶数 类推

最后为什么奇数是dp[m][1]
是因为,奇数保证最大 所以最后就dp到1截止了

而偶数则相反
that~s all

	ans = m & 1 ? dp[m][1] : dp[m][n]; 
	printf("%d",ans);

问题描述
  2015年,全中国实现了户户通电。作为一名电力建设者,小明正在帮助一带一路上的国家通电。
  这一次,小明要帮助 n 个村庄通电,其中 1 号村庄正好可以建立一个发电站,所发的电足够所有村庄使用。
  现在,这 n 个村庄之间都没有电线相连,小明主要要做的是架设电线连接这些村庄,使得所有村庄都直接或间接的与发电站相通。
  小明测量了所有村庄的位置(坐标)和高度,如果要连接两个村庄,小明需要花费两个村庄之间的坐标距离加上高度差的平方,形式化描述为坐标为 (x_1, y_1) 高度为 h_1 的村庄与坐标为 (x_2, y_2) 高度为 h_2 的村庄之间连接的费用为
  sqrt((x_1-x_2)(x_1-x_2)+(y_1-y_2)(y_1-y_2))+(h_1-h_2)*(h_1-h_2)。
  在上式中 sqrt 表示取括号内的平方根。请注意括号的位置,高度的计算方式与横纵坐标的计算方式不同。
  由于经费有限,请帮助小明计算他至少要花费多少费用才能使这 n 个村庄都通电。
输入格式
  输入的第一行包含一个整数 n ,表示村庄的数量。
  接下来 n 行,每个三个整数 x, y, h,分别表示一个村庄的横、纵坐标和高度,其中第一个村庄可以建立发电站。
输出格式
  输出一行,包含一个实数,四舍五入保留 2 位小数,表示答案。
样例输入
4
1 1 3
9 9 7
8 8 6
4 5 4
样例输出
17.41
评测用例规模与约定
  对于 30% 的评测用例,1 <= n <= 10;
  对于 60% 的评测用例,1 <= n <= 100;
  对于所有评测用例,1 <= n <= 1000,0 <= x, y, h <= 10000。
请选择编程语言

#include<stdio.h>
#include<math.h>
int maxn = 1001;
double MAX =99999999;
int n,vis[1001];
double a[1001][1001], d[1001], ans = 0.0;
double temp;
struct node {
    int x;
    int y;
    int h;
}p[1001];
double min(double a,double b)
{
	return a>b?b:a;
}
int main() 
{
	int i,j,k;
    scanf("%d",&n);
    for(i = 1; i <= n; i++)
        scanf("%d %d %d", &p[i].x, &p[i].y, &p[i].h);
	 for(i = 0; i <= n; i++) 
	 {
        d[i] = MAX;
     }  
    for( i = 1; i <= n - 1; i++)
        for( j = i + 1; j <= n; j++) {
            temp = sqrt( (p[i].x - p[j].x) * (p[i].x - p[j].x) + (p[i].y-p[j].y) * (p[i].y-p[j].y)) + (p[i].h-p[j].h) * (p[i].h-p[j].h);
            a[i][j] = a[j][i] = temp;
        }
    d[1] = 0;
    for(int i = 1; i < n; i++) {
         k = 0;
        for(int j = 1; j <= n; j++)
            if( !vis[j] && (k == 0 || d[j] < d[k])) 
			k = j;
			vis[k] = 1;
        for(int y = 1;  y <= n;  y++)
            if(!vis[y]) d[y] = min(d[y], a[k][y] );
    } 
    for(i = 2; i <= n; i++) 
	ans += d[i];
    printf("%.2f",ans);

    return 0;
}

这道题纯属不会,看了看别人的思想,没错,是最短路径,通过图的方式来做,真的很巧妙,当然对于初学图的我来讲,很是蒙蔽,羡慕就来讲讲这道题吧!

首先他采用 三个数组

a[1001][1001], d[1001],vis[1001]

分别储存图,上个节点到本节点的费用,标记有没有被访问过。

分别对这三个进行初始化 和相应的赋值;
d[1]=0;
是为了k=0做铺垫,便于每次都可以找出最少费用

 for(int i = 1; i < n; i++) {
         k = 0;
        for(int j = 1; j <= n; j++)
            if( !vis[j] && (k == 0 || d[j] < d[k])) 
			k = j;
			vis[k] = 1;
        for(int y = 1;  y <= n;  y++)
            if(!vis[y]) d[y] = min(d[y], a[k][y] );

我感觉这个是整个代码的灵魂, 通过第二个for找出和第一个for节点最近的节点,然后进行标记,第三个for则是找出的这个节点的接下来的这个节点的最短路径 然后标记,简直像极了最短路径,实在是秒啊!秒啊!
然后就是依次把图遍历玩就行,然后将最短路径相加就行了啊
实在是太秒了
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值