蓝桥杯省赛集训第二天

又是记录煤耗集训的一天~~~(喜

第一天传送门

第一题:数组-密码破译

水题我为什么要写(bushi

时间:1s 空间:256M

题目描述:

天天和亮亮会做些坏事。他们正在手机上互相发短信。明明已经明确拦截了他们通过技术手段发送的信息。但是,显然他无法理解这些信息。原因是此信息已加密。

这时,名侦探柯南发送了加密方法,你能帮忙解密这些信息吗?

已知所有信息都由小写字母组成。加密方法是将a改为b,b改为c,c改为d … z改为a(即将每个小写字母改成字母表中靠后的一个字母)。

输入格式:

由小写字母和空格组成的字符串。

输出格式:

表示解密后的信息的字符串。

样本输入1:

qzmf vn ldm xh ph pt fzm chzm gtzh rgh az
样本输出1:

rang wo men yi qi qu gan dian huai shi ba
样本输入2:

ygd fd sh lt ygdm rgh szh ihzm czm kd
样本输出2:

zhe ge ti mu zhen shi tai jian dan le

约定:

1<=字符串的长度<=100

getline很重要,避免吃空格

getline(cin,string);
#include<bits/stdc++.h>
using namespace std;
string s;
int n; 
int main(){
	getline(cin,s);
	for(int i=0;i<=s.size();i++){
		if(s[i]==' ')continue;
		if(s[i]=='z')s[i]='a';
		else s[i]=s[i]+1;
	}
	cout<<s;
}

#第二题 交换瓶子

时间:0.2s 空间:64M

【题目描述】

有N个瓶子,编号 1 ~ N,放在架子上。
比如有5个瓶子:
2 1 3 5 4
要求每次拿起2个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换2次就可以复位。
如果瓶子更多呢?你可以通过编程来解决。

【输入描述】

第一行: 一个正整数N(N<10000), 表示瓶子的数目
第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。

【输出描述】

输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。

【样例输入1】

5 
3 1 2 5 4

【样例输出1】

3

【样例输入2】

5 
5 4 3 2 1

【样例输出2】

2

我用的改进的选择排序,肥肠不戳:

#include<bits/stdc++.h>
using namespace std;
int n,a[114514],k,ans;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n-1;i++){
		k=i;
		for(int j=i+1;j<=n;j++){
			if(a[k]>a[j])k=j;
		}
		if(k!=i){
			swap(a[i],a[k]);
			ans++;
		}
	}
	printf("%d",ans);
}

第三题:买菜做饭

每日dp(1/2)

Description

为了做饭,出题人拿了 k 块钱,准备去买食材。出题人准备买一只螃蟹和若干蔬菜。菜场里有 n 只螃蟹,第 i只螃蟹的价格为 c_i​,美味值为 v_i,菜场里有 m 个蔬菜,第 i 个蔬菜的价格为 w_i,美味值为 p_i​,求出题人的钱能换来最大的美味值。

Input

第一行三个正整数 k,n,m,
接下来 n 行,每行两个正整数 c_i​,v_i,
接下来 m 行,每行两个正整数 w_i​,p_i,
相邻整数均以空格分开

Output

一行一个整数,表示出题人的钱能换来最大的美味值

Sample input

23 2 2

2 3

3 4

10 10

10 10

Sample output

24

Note

all the numbers <= 3000

Time and memory limit

1s ,512M

#include<bits/stdc++.h>
using namespace std;
int w[3010],v[3010],c[3010],p[3010],b[3010];//数组要开大一些
int main()
{
    int k,m,n;
    cin>>k>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>c[i]>>v[i];
    }
    for(int i=1;i<=m;i++)
    {
        cin>>w[i]>>p[i];
    }
    for(int i=1;i<=m;i++)
    {
        for(int j=k;j>=w[i];j--)
        {
            b[j]=max(b[j],b[j-w[i]]+p[i]);
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=c[i];j<=k;j++)
        {
            ans=max(ans,b[j-c[i]]+v[i]);
        }
    }
    printf("%d\n",ans);
    return 0;
}

第四题:走迷宫

时间限制:2s 空间限制:256M

描述

给定一个迷宫。在迷宫中有一些障碍物无法通过,请计算出从左上角到右下角的移动方案总数。(一个位置不能经过两次,只能上下左右四个方向走)

输入格式

第一行包含两个整数n,m,表示迷宫的大小。1 <= N,M<= 6

接下来的n行,每行包含m个字符,代表迷宫。

#代表障碍

*代表你可以去的位置

左上角和右下角用“*”表示

输出格式

一个整数。

样本输入1

5 6
*****#
*###*#
*###*#
*###*#
******

样本输出1

2

样本输入2

6 6
******
******
******
******
******
******

示例输出2

1262816

提示
下载 (1)

答辩的搜索题

试试Python吧!

def dfs(x,y):
    global a
    global method
    global n,m
    if x==n-1 and y==m-1:
        method+=1
        return
    if y<m-1 and a[x][y+1]=="*" and v[x][y+1]==0:
        v[x][y+1]=1
        dfs(x,y+1)
        v[x][y+1]=0          
    if x<n-1 and a[x+1][y]=="*" and v[x+1][y]==0:
        v[x+1][y]=1
        dfs(x+1,y)
        v[x+1][y]=0
    if y>0 and a[x][y-1]=="*" and v[x][y-1]==0:
        v[x][y-1]=1
        dfs(x,y-1)
        v[x][y-1]=0
    if x>0 and a[x-1][y]=="*" and v[x-1][y]==0:
        v[x-1][y]=1
        dfs(x-1,y)
        v[x-1][y]=0
    return
n,m=map(int,input().split())
a=[]
v=[[0 for i in range(m)] for i in range(n)]
method=0          
for i in range(n):
    a.append(list(input()))
v[0][0]=1
dfs(0,0)
print(method)

第五题:Maze Visit Order

给定一个 n 行 m 列的迷宫,找出访问的单元格顺序,每次尝试按上、左、右、下的给定顺序移动。迷宫由0和1组成,其中1表示墙,0表示可以进入的有效单元格。我们的起始位置在左上角(0, 0)。

1 ≤ n,m ≤ 100

输入:

第一行是两个用空格分隔的整数 n 和 m,其中 n 是迷宫的行数,m 是迷宫的列数。

接下来的 n 行有 m 个用空格分隔的整数,表示墙或开放单元格。

输出:

一个 n x m 的矩阵,其中每个单元格表示单元格被访问的顺序。如果该单元格无法被访问,则将其放置为0。

示例输入:

3 4

0 0 0 0

1 0 1 0

0 0 0 0

示例输出:

1 2 3 4

0 9 0 5

10 8 7 6

答辩的搜索+10086

用一条路走到黑的dfs,因为是一条路径

#include<bits/stdc++.h>
using namespace std;
int n,a[114][114],vis[114][114],m,k,sum;
//方向数组很重要,6次才AC
int dx[]={-1,0,0,1};
int dy[]={0,-1,1,0};
void dfs(int x,int y){
	if(sum==k+1){
		return;
	}
	for(int i=0;i<4;i++){
		int nx=x+dx[i],ny=y+dy[i];
		if(vis[nx][ny]==0 && nx>=1 && nx<=n && ny<=m && ny>=1){
			sum++;
			vis[nx][ny]=sum;
			dfs(nx,ny); 
		} 
	}
}
int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%d",&a[i][j]);
			if(a[i][j]==1){
				vis[i][j]=-1;
				continue;
			}
			k++;
		}
	}
	if(vis[1][1]==-1){
		for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			printf("0 ");
		}
		printf("\n");
	}
		return 0;
	}
	sum++;
	vis[1][1]=1;
	dfs(1,1);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(vis[i][j]==-1)printf("0 ");
			else printf("%d ",vis[i][j]);
		}
		printf("\n");
	}
}

第六题:制作沙拉

问题描述

有 n 个水果,每个水果有两个属性:美味值和卡路里值。

现在选用若干个(至少 1 个)水果制作一份特殊的沙拉,沙拉的美味值为所选的水果的美味值的和,沙拉的卡路里值为所选水果的卡路里值的和。

沙拉的美味值恰好是卡路里值的 K 倍。请计算该沙拉美味值最大为多少。

输入数据

第一行,两个整数 n, k (1 ≤ n ≤ 100, 1 ≤ k ≤ 10);

第二行,包含 n 个整数,a1, a2, …, an (1 ≤ ai ≤ 100),表示水果的美味值;

第三行,包含 n 个整数,b1, b2, …, bn (1 ≤ bi ≤ 100),表示水果的卡路里值。

输出数据

共一行,一个整数,表示最大美味值,若无解则输出-1。

样例输入1

3 2

10 8 1

2 7 1

样例输出1

18

样例输入2

5 3

4 4 4 4 4

2 2 2 2 2

样例输出2

-1

每日DP(2/2)

新奇的写法

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n,k;
int sp[101],cr[101],a[101],b[101],ta=0,tb=0,f[10001],g[10001];
int getVal(int t){
    return sp[t]-k*cr[t];
}
int main(){
    cin>>n>>k;
    for (int i=1;i<=n;i++)
        cin>>sp[i];
    for (int i=1;i<=n;i++)
        cin>>cr[i];
    int temp;
    for (int i=1;i<=n;i++){
        temp=getVal(i);
        if (temp>=0)
            a[ta++]=i;
        else if (temp<0)
            b[tb++]=i;
    }
    memset(f,0xf3,sizeof(f));
    memset(g,0xf3,sizeof(g));
    f[0]=0;
    g[0]=0;
    for (int i=0;i<ta;i++)
        for (int j=10000;j>=getVal(a[i]);j--)
            f[j]=max(f[j],f[j-getVal(a[i])]+sp[a[i]]);
    for (int i=0;i<tb;i++)
        for (int j=10000;j>=-getVal(b[i]);j--)
            g[j]=max(g[j],g[j+getVal(b[i])]+sp[b[i]]);
    int ss;
    int maxx=-1;
    for (ss=10000;ss>=1;ss--)
        if (f[ss]>0&&g[ss]>0){
            maxx=max(f[ss]+g[ss],maxx);
        }   
    cout<<maxx;
    return 0;
}

完成力(喜

8 个赞

好厉害啊:melting_face:

4 个赞

厉害+1
居然会那么多知识耶!!! :+1:

4 个赞

666

3 个赞

小伙汁未来可期!

4 个赞

66

4 个赞