目录
跳石板
链接:跳石板_牛客题霸_牛客网 (nowcoder.com)
来源:牛客网
描述
小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3.......
这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板
输入描述:
输入为一行,有两个整数N,M,以空格隔开。 (4 ≤ N ≤ 100000) (N ≤ M ≤ 100000)
输出描述:
输出小易最少需要跳跃的步数,如果不能到达输出-1
示例1
输入:
4 24
输出:
5
题解: 题目的意思是从N开始,最少需要累加几步可以变成指定的数字M,每次累加的值为当前值的一个约数。
做法:
代码 1
#include <iostream>
#include <vector>
#include <limits.h>
#include <math.h>
using namespace std;
//求约数
void get_div(int num, vector<int> &a) {
for (int i = 2; i <= sqrt(num); ++i) {
if (num % i == 0){
a.push_back(i);
if (num / i != i) {
a.push_back(num / i);
}
}
}
}
int min_step(int n, int m) {
//step表示所跳的方块所在的位置
//防止越界m+1从1开始不从0开始
vector<int> step(m + 1, INT_MAX);//int_max表示不可到达
step[n] = 0;//当前位置n的初始化,表示现在的位置不需要跳就为0
for (int i = n; i < m; ++i) {
if(step[i] == INT_MAX) {//如果当前位置是初始化的最大值那就不可到达
continue;
}
vector<int> a;
get_div(i, a);
//由位置i出发能到达的点为 step[a[j]+i]
//a[j] 当前位置的约数 i 当前的位置 m 跳到的目标
//a[j] + i 跳的下一个位置
for (int j = 0; j < a.size(); ++j) {
//需要挑选一个最小值
//寻找到最快能到的步数
//比如我在12最快可以到18就不考虑14和15和16
if (a[j] + i <= m && step[a[j] + i] != INT_MAX) {
step[a[j] + i] = step[a[j] + i] < step[i] + 1 ? step[a[j] + i] : step[i] + 1;
}else if (a[j] + i <= m) {
step[a[j] + i] = step[i] + 1;
}
}
}
return step[m] == INT_MAX ? -1 : step[m];
}
int main() {
int n, m, count;
while(cin >> n >> m) {
count = min_step(n, m);
cout << count << endl;
}
return 0;
}
代码2
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//计算约数,求除了1和本身的约数
void divisorNum(int n, vector<int>& divNum) {
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
divNum.push_back(i);
//非平方数时还有另一个数也要加入
if (n / i != i)
divNum.push_back(n / i);
}
}
}
int Jump(int N, int M) {
//储存的到达此stepNum点的步数,初始N为1步,从N到N为1步
vector<int> stepNum(M + 1, 0);
stepNum[N] = 1;
for (int i = N; i < M; i++)
{
//N的所有约数,即为从本身这个点开始能走的数量
vector<int> divNum;
//0代表这个点不能到
if (stepNum[i] == 0)
continue;
//求出所有能走的步数储存在divNum的容器中
divisorNum(i, divNum);
for (int j = 0; j < divNum.size(); j++)
{
//由位置i出发能到达的点为 stepNum[divNum[j]+i]
if ((divNum[j] + i) <= M && stepNum[divNum[j] + i] != 0)
stepNum[divNum[j] + i] = min(stepNum[divNum[j] + i],
stepNum[i] + 1);
else if ((divNum[j] + i) <= M)
stepNum[divNum[j] + i] = stepNum[i] + 1;
}
}
if (stepNum[M] == 0)
return -1;
else
//初始化时多给了一步,故需要减1
return stepNum[M] - 1;
}
int main() {
int n, m, count;
while(cin >> n >> m) {
count = min_step(n, m);
cout << count << endl;
}
return 0;
}
参数解析
链接:参数解析_牛客题霸_牛客网 (nowcoder.com)
来源:牛客网
描述
在命令行输入如下命令:
xcopy /s c:\\ d:\\e,
各个参数如下:
参数1:命令字xcopy
参数2:字符串/s
参数3:字符串c:\\
参数4: 字符串d:\\e
请编写一个参数解析程序,实现将命令行各个参数解析出来。
解析规则:
1.参数分隔符为空格
2.对于用""包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy /s "C:\\program files" "d:\"时,参数仍然是4个,第3个参数应该是字符串C:\\program files,而不是C:\\program,注意输出参数时,需要将""去掉,引号不存在嵌套情况。
3.参数不定长4.输入由用例保证,不会出现不符合要求的输入
数据范围:字符串长度:1\le s\le 1000\1≤s≤1000
进阶:时间复杂度:O(n)\O(n) ,空间复杂度:O(n)\O(n)
输入描述:
输入一行字符串,可以有空格
输出描述:
输出参数个数,分解后的参数,每个参数都独占一行
示例1
输入:
xcopy /s c:\\ d:\\e
输出:
4
xcopy
/s
c:\\
d:\\e
题解:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void analysis_str(string &str) {
string tmp = "";
vector<string> ss;
bool flag = false;
for (int i = 0; i < str.size(); ++i) {
//判断是否处于字符串状态
if (str[i] == '"') {
flag = !flag;
} else if (str[i] == ' ' && !flag) {//判断分隔符或者是否为字符串的内容
ss.push_back(tmp);
tmp = "";
}else {//正常参数内容
tmp += str[i];
}
}
ss.push_back(tmp);//这里需要将最后一次也要插入
cout << ss.size() << endl;
for (int i = 0; i < ss.size(); ++i) {
cout << ss[i] << endl;
}
}
int main() {
string str;
while (getline(cin, str)) {
analysis_str(str);
}
return 0;
}