学习C++从娃娃抓起!记录下CSP-J备考学习过程中的题目,记录每一个瞬间。
附上汇总贴:历年CSP-J初赛真题解析 | 汇总_csp历年真题_热爱编程的通信人的博客-CSDN博客
#include <algorithm>
#include <iostream>
using namespace std;
int n;
int d[50][2];
int ans;
void dfs(int n, int sum) {
if (n == 1) {
ans = max(sum, ans); //希望把n个合并到只剩一个时代价能够最大
return;
}
for (int i = 1; i < n; ++i) {
int a = d[i - 1][0], b = d[i - 1][1];
int x = d[i][0], y = d[i][1];
d[i - 1][0] = a + x; //枚举相邻的两个元素合并
d[i - 1][1] = b + y;
for (int j = i; j < n - 1; ++j) //抹去第i个元素
d[j][0] = d[j + 1][0], d[j][1] = d[j + 1][1];
int s = a + x + abs(b - y); //合并相邻两个元素的代价
dfs(n - 1, sum + s); //回溯法
for (int j = n - 1; j > i; --j) //还原第i个元素
d[j][0] = d[j - 1][0], d[j][1] = d[j - 1][1];
d[i - 1][0] = a, d[i - 1][1] = b;
d[i][0] = x, d[i][1] = y;
}
}
int main() {
cin >> n;
for (int i = 0; i < n; ++i)
cin >> d[i][0];
for (int i = 0; i < n; ++i)
cin >> d[i][1];
ans = 0;
dfs(n, 0);
cout << ans << endl;
return 0;
}
假设输入的n是不超过50的正整数,d[i][0]、d[i][1]都是不超过10000的正整数,完成下面的判断题和单选题:
28、若输入n为0,此程序可能会死循环或发生运行错误。( )
【答案】:错
【解析】
n=0时,整个循环不会执行,不会发生错误
29、若输入n为20,接下来的输入全为0,则输出为0。( )
【答案】:
【解析】
输入全为0时,s为0,sum也为0,所以ans也为0
30、输出的数一定不小于输入的d[i][0]和d[i][1]的任意一个。( 错 )
【答案】:错
【解析】
n=1时,没有合并,ans为0,此时不管d数组中值为多少。ans都会小于等于d数组中的数字,所以错误。
31、若输入的n为20,接下来的输入是20个9和20个0,则输出为( A )。
A.1890
B.1881
C.1908
D.1917
【答案】:B
【解析】
第一次合并的代价是18,第二次合并的代价是27,第三次合并的代价是36,....,最后一次合并的代价是9*20=180。
所以总的代价=9*2+9*3+9*4+...+9*20=1881
32、若输入的n为30,接下来的输入是30个0和30个5,则输出为( )。
A.2000
B.2010
C.2030
D.2020
【答案】:C
【解析】
第一次合并的代价是0,第二次合并的代价是5,第三次合并的代价是10,...,最后一次合并的代价是28*5。
所有总的代价=0+5*1+5*2+...+5*28=2030
33、若输入的n为15,接下来的输入是15到1,以及15到1,则输出为( C )。
A.2440
B.2220
C.2240
D.2420
【答案】:C
【解析】
第一次合并的代价是30,第二次合并的代价是58,第三次合并的代价是84,第四次合并的代价是108,第五次合并的代价是130,第六次合并的代价是150,第七次合并的代价是168,第八次合并的代价是184,第九次合并的代价是198,第十次合并的代价是210,第十一次合并的代价是220,第十二次合并的代价是228,第十三次合并的代价是234,第十四次合并的代价是238。
所有总的代价=30+58+84+108+...+238=2240,选C