7-1 计算数列第n项 计算
后一项是前一项三次方+1的各位数之和
A0 到 A1 是计算了一回
那么A0 到 An 是计算n回
#include<bits/stdc++.h>
using namespace std;
int main() {
int a0, n;
scanf("%d %d", &a0, &n);
long long an = a0;
for (int i = 0; i < n; ++i) {
an = an * an * an + 1;
int sum = 0;
while (an != 0) {
sum += an % 10;
an /= 10;
}
an = sum;
}
printf("%lld", an);
return 0;
}
7-2 AB变换 map容器
""不断执行变换 A 或变换 B,执行了 m 次变换后,产生的 m 个数字中有多少个不大于 K 的不同的数字?"" 用map去重
#include<bits/stdc++.h>
using namespace std;
int main() {
int m, sum = 0, k, c = 0;
cin >> m >> k;
char t;
map<int, int> v;
for (int i = 0; i < m; ++i) {
cin >> t;
if (t == 'A') sum /= 4;
else sum = sum * 8 + 1;
if (sum <= k) ++v[sum];
}
printf("%d", v.size());
return 0;
}
7-3 中秋福利
- 首先在一行中输出预算范围内(闭区间)一共有多少商品可选、以及区间内价格最高的商品的价格,数字间以一个空格分隔
- 随后在下面一行中输出该商品的 ID。如果有并列,则按照它们在输入中出现的顺序输出,每行一个。
- 如果区间内没有可选的商品,则在一行中输出所有商品中的最低、最高价格,数字间以一个空格分隔。
min max 存储最低最高价格以防止将来没有可选商品要输出所有商品中的最低、最高价格
m 保存合法区间内最高价格
最后判断v容器大小如果为空则输出所有商品中的最低、最高价格 不为空则输出一共有多少商品可选、以及区间内价格最高的商品的价格 有并列则按照输入顺序输出 一行一个
#include<bits/stdc++.h>
using namespace std;
int main() {
int N, a, b, c = 0, t1, t2, m = 0, min = 100000000, max = 0;
cin >> N >> a >> b;
vector<int> v;
for (int i = 0; i < N; ++i) {
cin >> t1 >> t2;
if (t2 < min) min = t2;
if (t2 > max) max = t2;
if (t2 <= b && t2 >= a) {
if (t2 > m) {
m = t2;
v.clear();
v.push_back(t1);
} else if (t2 == m) v.push_back(t1);
++c;
}
}
if (c) {
printf("%d %d\n", c, m);
for (int a : v)
printf("%08d\n", a);
} else printf("%d %d\n", min,max);
return 0;
}
7-4 爆气球 暴力
本人一开始的思路是从最左侧气球坐标 - 臂长开始遍历 到 最后一个最右侧气球坐标 - 臂长 这样显然有点麻烦 遍历太多 而且需要确定左右端点对应坐标元素的下标
后来想了想 ""如果这个坐标不唯一,输出最小的那个值。"" 也就是说最先能到达最大数量区间的坐标的跳跃落脚点就是结果 那么每次臂展区间的右端肯定是刚好到达一个坐标元素 那么每次确定好臂展的右侧端点为每个坐标元素 左侧端点对应的气球坐标下标结算出来 右减去左得到数量 找到最大数量即可
loc表示落脚点坐标 max表示最大能弄爆的气球数量
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, h, max = 0, loc;
cin >> n >> h;
int a[n];
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i) {
int le = a[i] - h;
int j = i - 1;
for (j; j > -1; --j)
if (a[j] <= le) break;
if ((j == -1 || le != a[j])) {
if (i - j > max) {
max = i - j;
loc = le;
}
} else if (i - j + 1 > max) {
max = i - j + 1;
loc = le;
}
}
cout << loc << " " << max;
return 0;
}
7-5 快排第二轮 排序
""
样例提示:
第 1 组数据是可能的,因为第一轮可以选 72 为主元,第二轮可以选 28 为主元。
第 2 组数据是可能的,因为第一轮可以选 2 为主元,第二轮可以选 72 为主元。反之亦然。
第 3 组数据是可能的,因为第一轮可以选 28 为主元,第二轮可以选 2 和 32 分别为左右两边子序列的主元。
第 4 组数据是不可能的,因为如果第一轮选 12 为主元,则第二轮左边子序列没有元素是主元;或者如果第一轮选 32 为主元,则第二轮右边子序列没有元素是主元。
""
认真读样例提示 理论上会做这道题代码很简单了就
判断主元这个东西有两种方法我在原来的博客里写过 如果这个元素是主元则在把全部序列排序后其位置是不变的例如
2 1 3 5 4 全部排序后为1 2 3 4 5我们发现3的位置不变 但是他不一定主元 主元一定位置不变 位置不变不一定主元要分清楚关系
比如 2 5 3 1 4 排序后为1 2 3 4 5 3的位置虽然不变但是左侧有个5大于3所以仍然不是主元所以要判断位置不变的元素的左侧最大元素要小于等于它 两个条件都符合才是主元
还有一种就是判断左右区间元素是否都小于等于 和 大于等于它 这个就不细述了 我之前的的博客有写过
如果主元数量为2 合法的结果一定有一个主元在左右两侧端点
主元数量大于2一定合法
主元数量小于2一定不合法
#include<bits/stdc++.h>
using namespace std;
int main() {
int k, n;
scanf("%d", &k);
for (int i = 0; i < k; ++i) {
bool f = 1;
vector<int> v;
scanf("%d", &n);
int a[n] = {0}, max = 0, min = 1000000000, b[n] = {0};
for (int j = 0; j < n; ++j) {
scanf("%d", &a[j]);
if (a[j] >= max) {
max = a[j];
b[j] = 1;
}
}
for (int j = n - 1; j > -1; --j) {
if (a[j] <= min) min = a[j];
else b[j] = 0;
if (b[j]) v.push_back(j);
}
if ((v.size() == 2 && (v[0] != 0 && v[1] != 0 && v[1] != n - 1 && v[0] != n - 1)) || v.size() < 2) f = 0;
if (f) printf("Yes\n");
else printf("No\n");
}
return 0;
}