2022-01-18每日刷题打卡
一本通
1257:Knight Moves
题目描述】
输入nn代表有个n×nn×n的棋盘,输入开始位置的坐标和结束位置的坐标,问一个骑士朝棋盘的八个方向走马字步,从开始坐标到结束坐标可以经过多少步。
【输入】
首先输入一个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;
}