2022-01-18每日刷题打卡

2022-01-18每日刷题打卡

一本通

1257:Knight Moves

题目描述】

输入nn代表有个n×nn×n的棋盘,输入开始位置的坐标和结束位置的坐标,问一个骑士朝棋盘的八个方向走马字步,从开始坐标到结束坐标可以经过多少步。

img

【输入】

首先输入一个nn,表示测试样例的个数。

每个测试样例有三行。

第一行是棋盘的大小L(4≤L≤300)L(4≤L≤300);

第二行和第三行分别表示马的起始位置和目标位置(0…L−1)(0…L−1)。

【输出】

马移动的最小步数,起始位置和目标位置相同时输出00。

【输入样例】

3 
8 
0 0 
7 0 
100 
0 0 
30 50 
10 
1 1 
1 1`
【输出样例】`
5 
28 
0 

广度优先搜索解法,和之前的走迷宫差不多,只不过走迷宫是四个方向,而这里是把它可能走的八个方向都存下来,以他给的起点出发开始bfs,当到达题目给的终点时把步数输出。

#include<iostream>
using namespace std;
#include<vector>
#include<string.h>
#include<algorithm>

typedef pair<int, int>PII;

const int N = 310;
int n, m, a, b, c, e;
int h[N][N];
int d[8][2] = { {1,2},{-1,2},{1,-2},{-1,-2},{2,1},{-2,1},{2,-1},{-2,-1} };
PII que[8 * N * N];

int bfs()
{
    if (a == c && b == e)return 0;
    memset(h, -1, sizeof h);
    int hh = 0, tt = 0;
    que[0] = { a,b };
    h[a][b] = 0;

    while (hh <= tt)
    {
        auto t = que[hh++];
        for (int i = 0; i < 8; i++)
        {
            int x = d[i][0] + t.first, y = d[i][1] + t.second;
            if (x >= 0 && x < m && y >= 0 && y < m && h[x][y] == -1)
            {
                h[x][y] = h[t.first][t.second] + 1;
                que[++tt] = { x,y };
            }
        }
    }
    return h[c][e];
}

int main()
{
    cin >> n;
    while (n--)
    {
        cin >> m >> a >> b >> c >> e;
        cout << bfs() << endl;
    }

    return 0;
}
1253:抓住那头牛

【题目描述】

农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0≤N≤100000)N(0≤N≤100000),牛位于点K(0≤K≤100000)K(0≤K≤100000)。农夫有两种移动方式:

1、从XX移动到X−1X−1或X+1X+1,每次移动花费一分钟

2、从X移动到2×X2×X,每次移动花费一分钟

假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?

【输入】

两个整数,NN和KK。

【输出】

一个整数,农夫抓到牛所要花费的最小分钟数。

【输入样例】

5 17
【输出样例】
4

这一回是从二维的迷宫变成一维的了,更方便了,二维走迷宫四个方向,这里只有向前向后了,只不过向前有走一步(+1)和跳一步(*2),所以一共是三个方向,用走迷宫的解法即可。

#include<iostream>
using namespace std;
#include<vector>
#include<string.h>
#include<algorithm>

const int N = 1e5 + 10;
int q[N], h[N];
int bfs(int a, int b)
{
    memset(h, -1, sizeof h);
    q[0] = a;
    h[a] = 0;
    int hh = 0, tt = 0;
    while (hh <= tt)
    {
        int t = q[hh++];
        if (t == b)
            return h[b];
        if (t + 1 <= 1e5 && h[t + 1] == -1)
        {
            q[++tt] = t + 1;
            h[t + 1] = h[t] + 1;
        }
        if (t - 1 >=0 && h[t - 1] == -1)
        {
            q[++tt] = t - 1;
            h[t - 1] = h[t] + 1;
        }
        if (t * 2 <= 1e5 && h[2 * t] == -1)
        {
            q[++tt] = t * 2;
            h[t * 2] = h[t] + 1;
        }
    }
    return h[b];
}

int main()
{
    int a, b;
    cin >> a >> b;
    cout<<bfs(a, b);

    return 0;
}

蓝桥杯——算法提高

算法提高 最大可能整数

问题描述

原本有一个很大的正整数,由于某种原因,他被按位分割成了n段。现给定这n个段小整数,问原来的整数最大可能是多少?

输入格式

第一行一个n,如问题描述所述。
  第二行n个数,分别表示n段具体的数。

输出格式

一行,表示最大整数。

样例输入

3
3 2 12

样例输出

3212

数据规模和约定

n<=1000,保证所有读入的数在32位内且没有前导0。

自定义排序,当ab形式拼接大于ba形式时,a排在b前面,否则b排在a前面。最后遍历一遍排序好的数组,把所有元素拼接起来即可。

#include<iostream>
using namespace std;
#include<vector>
#include<string.h>
#include<algorithm>

bool cmp(string a, string b)
{
    string str1 = a + b, str2 = b + a;
    return str1 > str2;
}

int main()
{
    int n;
    cin >> n;
    string str;
    vector<string>v(n);
    for (int i = 0; i < n; i++)cin >> v[i];
    sort(v.begin(), v.end(), cmp);
    for (int i = 0; i < n; i++)
        str += v[i];
    cout << str << endl;

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值