为了更好的阅读体检,可以查看我的算法学习网
本题在线评测链接:P1348
题目描述
跳房子,也叫跳飞机,是一种世界性的儿童游戏。
游戏参与者需要分多个回合按顺序跳到第 1 1 1格直到房子的最后一格
跳房子的过程中,可以向前跳,也可以向后跳。
假设房子的总格数是 c o u n t count count,小红每回合可能连续跳的步教都放在数组 s t e p s steps steps中,请问数组中是否有一种步数的组合,可以让小红两个回合跳到最后一格?
如果有,请输出索引和最小的步数组合。
注意:
- 数组中的步数可以重复,但数组中的元素不能重复使用。
- 提供的数据保证存在满足题目要求的组合,且索引和最小的步数组合是唯一的。
输入描述
第一行输入为房子总格数 c o u n t count count,它是 i n t int int整数类型。
第二行输入为每回合可能连续跳的步数,它是 i n t int int整数数组类型。
输出描述
返回索引和最小的满足要求的步数组合(顺序保持 s t e p s steps steps中原有顺序)
备注
-
c
o
u
n
t
≤
1000
count \leq 1000
count≤1000
-
0
≤
s
t
e
p
s
.
l
e
n
g
t
h
≤
5000
0 \leq steps.length \leq 5000
0≤steps.length≤5000
-
−
100000000
≤
s
t
e
p
s
≤
100000000
-100000000 \leq steps \leq 100000000
−100000000≤steps≤100000000
样例
输入
[1,4,5,2,2]
7
输出
[5, 2]
说明
无
输入
[-1,2,4,9,6]
8
输出
[-1, 9]
说明
此样例有多种组合满足两回合跳到最后,譬如: [ − 1 , 9 ] [-1,9] [−1,9], [ 2 , 6 ] [2,6] [2,6],其中 [ − 1 , 9 ] [-1,9] [−1,9]的索引和为 0 + 3 = 3 0+3=3 0+3=3, [ 2 , 6 ] [2,6] [2,6]的索和为 1 + 4 = 5 1+4=5 1+4=5,所以索引和最小的步数组合 [ − 1 , 9 ] [-1,9] [−1,9]
思路:暴力
读入后直接暴力判断,即第一层循环固定一个数,第二层循环去找是否有数匹配,若匹配则判断索引大小
本题有更优的解法,详细看P13028
代码
C++
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
int main() {
char c;
int x;
vector<int> a;
while (~scanf("%c%d", &c, &x)) {
a.push_back(x);
}
int n = a.back(), m = a.size() - 1;
a.pop_back();
int minn = 2 * n, ans1 = -1, ans2 = -1;
for (int i = 0; i < m; ++i) { // 循环遍历第一个数
for (int j = i + 1; j < m; ++j) { // 寻找是否有数匹配
if (a[i] + a[j] == n && i + j < minn) { // 记录答案
ans1 = a[i], ans2 = a[j];
minn = i + j;
}
}
}
printf("[%d, %d]", ans1, ans2);
return 0;
}
Python
a = list(map(int, input()[1:-1].split(',')))
n = int(input())
m = len(a)
minn = 2 * n
ans1 = -1
ans2 = -1
for i in range(m): # 循环遍历第一个数
for j in range(i + 1, m): # 寻找是否有数匹配
if a[i] + a[j] == n and i + j < minn: # 记录答案
ans1 = a[i]
ans2 = a[j]
minn = i + j
print(f"[{ans1}, {ans2}]")
Java
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
int[] a =
Arrays.stream(s.substring(1, s.length() - 1).split(","))
.mapToInt(Integer::parseInt)
.toArray();
int n = scanner.nextInt();
int m = a.length;
int minn = 2 * n;
int ans1 = -1, ans2 = -1;
for (int i = 0; i < m; ++i) { // 循环遍历第一个数
for (int j = i + 1; j < m; ++j) { // 寻找是否有数匹配
if (a[i] + a[j] == n && i + j < minn) { // 记录答案
ans1 = a[i];
ans2 = a[j];
minn = i + j;
}
}
}
System.out.printf("[%d, %d]", ans1, ans2);
}
}
JavaScript
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', (s) => {
const a = s.substring(1, s.length - 1).split(",").map(Number);
rl.on('line', (n) => {
n = parseInt(n);
const m = a.length;
let minn = 2 * n;
let ans1 = -1, ans2 = -1;
for (let i = 0; i < m; ++i) { // 循环遍历第一个数
for (let j = i + 1; j < m; ++j) { // 寻找是否有数匹配
if (a[i] + a[j] === n && i + j < minn) { // 记录答案
ans1 = a[i];
ans2 = a[j];
minn = i + j;
}
}
}
console.log(`[${ans1},${ans2}]`);
rl.close();
});
});
Go
package main
import (
"fmt"
"strings"
"strconv"
)
func main() {
var s string
fmt.Scan(&s)
s = strings.Trim(s, "[]")
nums := strings.Split(s, ",")
a := make([]int, len(nums))
for i, numStr := range nums {
a[i], _ = strconv.Atoi(strings.TrimSpace(numStr))
}
var n int
fmt.Scan(&n)
m := len(a)
minn := 2 * n
ans1, ans2 := -1, -1
for i := 0; i < m; i++ { // 循环遍历第一个数
for j := i + 1; j < m; j++ { // 寻找是否有数匹配
if a[i] + a[j] == n && i + j < minn { // 记录答案
ans1 = a[i]
ans2 = a[j]
minn = i + j
}
}
}
fmt.Printf("[%d, %d]", ans1, ans2)
}
时间复杂度
O ( n 2 ) O(n^2) O(n2)