目录
1.🌟金币
📕题目描述:
国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。
请计算在前K天里,骑士一共获得了多少金币。
骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,每天收到三枚金币。因此一共收到 1+2+2+3+3+3=14 枚金币。
对于 100%的数据,1 ≤ K ≤ 10,000
输入格式
一个正整数K,表示发放金币的天数。
输出格式
一个正整数,即骑士收到的金币数。
输入1:
6
输出1:
14
输入2:
1000
输出2:
29820
☀️思路:
模拟
求1+(1+2)+(1+2+3)…+(1+2+…+n)模型
#include<bits/stdc++.h>
using namespace std;
int i, j;
int n, sum = 0;
int main() {
cin >> n;
for (i = 1; i <= n; i++) { //控制括号的个数
for (j = 1; j <= i; j++) { //计算每个括号内的数据,每次j从1开始加到i(i即是每个括号中所加到的最大的一个数)
sum += j;
}
}
cout << sum;
}
本题的模型:1+(2+2)+(3+3+3)…+(n+n+n+.....)
✏️代码 :
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int ans;//记录天数
int sum;//金币总和
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
sum+=i;
ans++;
if(ans==n) cout<<sum;
}
}
return 0;
}
2.🌟
📕题目描述:
一般来说,一个正整数可以拆分成若干个正整数的和。
例如,1=1,10=1+2+3+4 等。对于正整数 n 的一种特定拆分,我们称它为“优秀的”,当且仅当在这种拆分下,n 被分解为了若干个不同的 2 的正整数次幂。注意,一个数 x 能被表示成 2 的正整数次幂,当且仅当 x 能通过正整数个 2 相乘在一起得到。
例如,
是一个优秀的拆分。但是,
就不是一个优秀的拆分,因为 1 不是 2 的正整数次幂。
现在,给定正整数 n,你需要判断这个数的所有拆分中,是否存在优秀的拆分。若存在,请你给出具体的拆分方案
输入描述
输入只有一行,一个整数 n ( 1 ~10^7)n (1≤n≤10^7),代表需要判断的数。
输出描述
如果这个数的所有拆分中,存在优秀的拆分。那么,你需要从大到小输出这个拆分中的每一个数,相邻两个数之间用一个空格隔开。可以证明,在规定了拆分数字的顺序后,该拆分方案是唯一的。
若不存在优秀的拆分,输出 -1
。
输入1:
6
输出1:
4 2
输入2:
7
输出2:
-1
☀️思路:
一个数的二进制数就是由(2^0+2^1+2^2+.....2^n)组成
所以可以将输入数转换为二进制
我使用bitset进行二进制转换和处理
注意:使用pow时默认返回浮点数,要用(int)强制转换一下,否则当数字很大时,浮点数会用科学计数法表示,从而出现错误
✏️代码 :
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<bitset>
#include<math.h>
using namespace std;
const int N = 32 ;
int n;
int a[N];
int main() {
cin >> n;
bitset<24>t(n);//转换为二进制
for (int i = 23; i >= 0; i--) {
if (t[0] & 1) { //判断末尾是否为1
puts("-1");
return 0;
}
if (t[i] & 1) cout << (int)pow(2, i) << " "; //pow返回浮点数,数据大时会使用科学计数法表示,所以要转换为(int)
}
return 0;
}
3.🌟穿越雷区
📕题目描述:
X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
坦克车只能水平或垂直方向上移动到相邻的区。
输入格式
输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
A,B都只出现一次。
输出格式
要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1
输入:
5 A + - + - - + - - + - + + + - + - + - + B + - + -
输出
10
☀️思路:
上来先套个bfs模板,vis数组标记是否走过,d数组记录步数,mp字符数组记录地图
注意:题意说它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,
只需要比较前后两个位置的字符是否相同即可
✏️代码 :
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<queue>
using namespace std;
const int N = 101 ;
#define x first
#define y second
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
char mp[N][N];//地图
int d[N][N];//步数
bool vis[N][N];//标记走过
int n;
typedef pair<int, int>PII;
int bfs(PII start, PII end) {
queue<PII>q;
memset(d, -1, sizeof(d));
q.push(start);//起点入队
d[start.x][start.y] = 0;
vis[start.x][start.y] = 1;
while (q.size()) {
PII t = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int fx = t.x + dx[i], fy = t.y + dy[i];
if (fx < 1 || fy < 1 || fx > n || fy > n) continue; //越界
if (mp[fx][fy] == mp[t.x][t.y]) continue; //前后两个点相同辐射
if (vis[fx][fy]) continue;
d[fx][fy] = d[t.x][t.y] + 1;//步数+1
vis[fx][fy] = 1;
q.push({fx, fy});
}
}
return d[end.x][end.y];
}
int main() {
cin >> n;
PII start, end;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> mp[i][j];
if (mp[i][j] == 'A') start = {i, j};
if (mp[i][j] == 'B') end = {i, j};
}
}
cout << bfs(start, end);
return 0;
}
最后一题没做出来,后续再补充