[蓝桥杯][2019年第十届真题]旋转、扫地机器人、Fibonacci 数列与黄金分割、后缀表达式

个人题解链接,历届试题,正在更新中~

旋转

题目描述
图片旋转是对图片最简单的处理方式之一,在本题中,你需要对图片顺时 针旋转 90 度。

我们用一个 n × m 的二维数组来表示一个图片,例如下面给出一个 3 × 4 的 图片的例子:

1 3 5 7

9 8 7 6

3 5 9 7

这个图片顺时针旋转 90 度后的图片如下:

3 9 1

5 8 3

9 7 5

7 6 7

给定初始图片,请计算旋转后的图片

输入
输入的第一行包含两个整数 n 和 m,分别表示行数和列数。
接下来 n 行,每行 m 个整数,表示给定的图片。图片中的每个元素(像

素)为一个值为 0 至 255 之间的整数(包含 0 和 255)。

输出
输出 m 行 n 列,表示旋转后的图片。

样例输入
3 4
1 3 5 7
9 8 7 6
3 5 9 7
样例输出*
3 9 1
5 8 3
9 7 5
7 6 7

思路:
水题不谈,换个方向输出即可

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double Pi = acos(-1);
namespace {
  template <typename T> inline void read(T &x) {
    x = 0; T f = 1;char s = getchar();
    for(; !isdigit(s); s = getchar()) if(s == '-') f = -1;
    for(;  isdigit(s); s = getchar()) x = (x << 3) + (x << 1) + (s ^ 48);
    x *= f;
  }
}
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) x & (-x)
#define pii pair<int,int>
#define fi first
#define se second
int a[1005][1005];
int main() {
  int n, m; read(n); read(m);
  _rep(1, n, i) _rep(1, m, j) read(a[i][j]);
  _rep(1, m, i) for(int j = n; j >= 1; j--) printf("%d%c", a[j][i], " \n"[j==1]);
}

扫地机器人

题目描述
小明公司的办公区有一条长长的走廊,由 N 个方格区域组成,如下图所示。

在这里插入图片描述

走廊内部署了 K 台扫地机器人,其中第 i 台在第 Ai 个方格区域中。

已知扫地机器人每分钟可以移动到左右相邻的方格中,并将该区域清扫干净

请你编写一个程序,计算每台机器人的清扫路线,使得

  1. 它们最终都返回出发方格,

  2. 每个方格区域都至少被清扫一遍,

  3. 从机器人开始行动到最后一台机器人归位花费的时间最少。

注意多台机器人可以同时清扫同一方块区域,它们不会互相影响

输出最少花费的时间。

在上图所示的例子中,最少花费时间是 6。第一台路线:2-1-2-3-4-3-2,清 扫了 1、2、3、4 号区域。第二台路线 5-6-7-6-5,清扫了 5、6、7。第三台路线 10-9-8-9-10,清扫了 8、9 和 10。

输入
第一行包含两个整数 N 和 K。

接下来 K 行,每行一个整数 Ai。

输出
输出一个整数表示答案

样例输入
10 3
5
2
10
样例输出
6

思路
二分可移动的最小的区间使得可以覆盖整个线段,总步数为 2 ∗ l − 2 2*l-2 2l2

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double Pi = acos(-1);
namespace {
  template <typename T> inline void read(T &x) {
    x = 0; T f = 1;char s = getchar();
    for(; !isdigit(s); s = getchar()) if(s == '-') f = -1;
    for(;  isdigit(s); s = getchar()) x = (x << 3) + (x << 1) + (s ^ 48);
    x *= f;
  }
}
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) x & (-x)
#define pii pair<int,int>
#define fi first
#define se second
int a[100005];
int n, k;
bool judge(int x) {
  int l = 0;
  for(int i = 1; i <= k; i++) {
    if(a[i] - x <= l) {
      if(a[i] <= l) l = a[i] + x - 1;
      else l = l + x;
    } else return false;
  }
  return l >= n;
}
int main() {
  read(n); read(k);
  _rep(1, k, i) read(a[i]);
  sort(a + 1, a + k + 1);
  int l = 0, r = 2 * n, ans;
  while(l <= r) {
    int mid = l + r >> 1;
    if(judge(mid)) ans = mid, r = mid-1;
    else l = mid + 1;
  }
  cout << (ans-1)*2 << endl;
}

Fibonacci 数列与黄金分割

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double Pi = acos(-1);
namespace {
  template <typename T> inline void read(T &x) {
    x = 0; T f = 1;char s = getchar();
    for(; !isdigit(s); s = getchar()) if(s == '-') f = -1;
    for(;  isdigit(s); s = getchar()) x = (x << 3) + (x << 1) + (s ^ 48);
    x *= f;
  }
}
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) x & (-x)
#define pii pair<int,int>
#define fi first
#define se second
LL f[100];
int main() {
  f[1] = f[2] = 1;
  for(int i = 3; i <= 54; i++) {
    f[i] = f[i-1] + f[i-2];
  }int n; read(n);
  if(n <= 53) printf("%.8lf\n", f[n]*1.0/f[n+1]);
  else printf("%.8lf\n", f[53]*1.0/f[54]);
}

题目描述
Fibonacci 数列是非常著名的数列:

F[1] = 1,

F[2] = 1,

对于 i > 3,F[i] = F[i − 1] + F[i − 2]

Fibonacci 数列有一个特殊的性质,前一项与后一项的比值,F[i]/F[i + 1], 会趋近于黄金分割。

为了验证这一性质,给定正整数 N,请你计算 F[N]/F[N + 1],并保留 8 位 小数。

输入
一个正整数 N。(1 ≤ N ≤ 2000000000)

输出
F[N]/F[N + 1]。答案保留 8 位小数。

样例输入
2
样例输出
0.50000000

思路
我们知道相邻两数的差会越来越接近黄金比例,所以可以打表看看多少位之后就不会变了。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double Pi = acos(-1);
namespace {
  template <typename T> inline void read(T &x) {
    x = 0; T f = 1;char s = getchar();
    for(; !isdigit(s); s = getchar()) if(s == '-') f = -1;
    for(;  isdigit(s); s = getchar()) x = (x << 3) + (x << 1) + (s ^ 48);
    x *= f;
  }
}
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) x & (-x)
#define pii pair<int,int>
#define fi first
#define se second
LL f[100];
int main() {
  f[1] = f[2] = 1;
  for(int i = 3; i <= 54; i++) {
    f[i] = f[i-1] + f[i-2];
  }int n; read(n);
  if(n <= 53) printf("%.8lf\n", f[n]*1.0/f[n+1]);
  else printf("%.8lf\n", f[53]*1.0/f[54]);
}

后缀表达式

题目描述
给定 N 个加号、M 个减号以及 N + M + 1 个整数 A1, A2, · · · , AN+M+1,小 明想知道在所有由这 N 个加号、M 个减号以及 N + M + 1 个整数凑出的合法的 后缀表达式中,结果最大的是哪一个?

请你输出这个最大的结果。
例如使用1 2 3 + -,则 “2 3 + 1 -” 这个后缀表达式结果是 4,是最大的。

输入
第一行包含两个整数 N 和 M。
第二行包含 N + M + 1 个整数 A1, A2, · · · , AN+M+1。

输出
输出一个数,表示答案
样例输入
1 1
1 2 3
样例输出
4

思路
蓝桥杯的模拟题一般都是想起来复杂,但是实现起来简单,要考虑好来再写。后缀表达式是可以任意添加括号的
我们分情况讨论:

  • 无负数,所有数相加即可
  • 无负数有负号,添加括号可以使负号变成正号,但是还是会减去一个数,那就减去最小的正数即可
  • 无正数有负号,同上,还是会有一个负数无法变成正数,所以要减去最大的负数
  • 有正有负,可以看成上面两种情况的,一个会减去一个数,那么我们让减去的这个数为负数,一个是加上一个数,我们就加上一个正数,所以最后的结果是不会有损失,即为所有数的绝对值之和
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double Pi = acos(-1);
namespace {
  template <typename T> inline void read(T &x) {
    x = 0; T f = 1;char s = getchar();
    for(; !isdigit(s); s = getchar()) if(s == '-') f = -1;
    for(;  isdigit(s); s = getchar()) x = (x << 3) + (x << 1) + (s ^ 48);
    x *= f;
  }
}
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i <  (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define _srep(n,m,i)for (register int i = (n); i >= (m); i--)
#define _sfor(n,m,i)for (register int i = (n); i >  (m); i--)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) x & (-x)
#define pii pair<int,int>
#define fi first
#define se second
int main() {
  int n, m; read(n); read(m);
  LL z = 0, f = 0, Min_z = 1e15, Max_f = -1e15, a;
  _rep(1, n+m+1, i) {
    read(a);
    if(a < 0) f += a, Max_f = max(Max_f, a);
    else z += a, Min_z = min(Min_z, a);
    if(a == 0) Min_z = Max_f = 0;
  }
  if(!m) printf("%lld\n", z + f);
  else if(!f) printf("%lld\n", z - 2 * Min_z);
  else if(!z) printf("%lld\n", -f + 2 * Max_f);
  else printf("%lld\n", z - f);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值