单项选择题
第1题
执行 cout << '9'*3; 语句后,输出的结果是( )。
A. 27
B. 9*3
C. 999
D. 171
答案:D
解析:char类型与int类型的计算结果为int,9的ASCII码为57,所以最终输出171。
第2题
已定义:int a = 02023, b = 0x212; a + b 的值是( )。
A. 八进制数4771
B. 十进制数1573
C. 十进制数2553
D. 十六进制数9f9
答案:B
解析:首先a转二进制为:0100 0001 0011
b转二进制为:0010 0001 0010
求和:1100 0100 0101
转八进制:6105
转十六进制:C45转十进制:1573
第3题
执行以下代码,输出的结果是( )。
#include <iostream>
using namespace std;
int func(int x){
if (x <= 4)
return 2 * x - 1;
else if (x > 7)
return func(x - 4) + x;
else
return func(x + 3) + 2;
}
int main(){
cout << func(10);
return 0;
}
A. 26
B. 29
C. 38
D. 45
答案:C
解析:
f(10) = f(6) + 10
f(6) = f(9) + 2
f(9) = f(5) + 9
f(5) = f(8) + 2
f(8) = f(4) + 8
当 x = 4 时,返回值为 2 * 4 - 1 = 7。
f(10) = 7 + 8 + 2 + 9 + 2 + 10 = 38。
第4题
下列选项中,判断a不等于0且b不等于0的正确的条件表达式是( )。
A. !(a==0 && b==0)
B. !a=0 && !b=0
C. a && b
D. !((a!=0) && (b!=0))
答案:C
第5题
执行语句 int a[3][4] = {{1, 2}, {3}, {4, 5, 6, 7}}; 后,a[1][2] 和a[2][1] 的值分别为:( )。
A. 2、3
B. 0、5
C. 2、5
D. 5、0
答案:B
解析:该数组三行四列,未赋值元素的值都为0。
程序设计题
第1题 促销活动
int n;
cin >> n;
cout << n - n / 200 * 25 << endl;
第2题 相邻身高差
#include <iostream>
#include <cmath>
using namespace std;
int n;
int a[110];
int res = 0;
int main() {
cin >> n;
for(int i = 1; i <= n; i++){
cin >> a[i];
if(i >= 2)
res = max(res, abs(a[i] - a[i - 1]));
}
cout << res << endl;
return 0;
}
第3题 九进制回文数
主要逻辑:从n到m之间进行枚举,对于每一个数,判断是否是九进制回文数,且每一位都是奇数。
#include <iostream>
#include <cstdio>
using namespace std;
int n, m;
int res = 0;
bool is_huiwen(int n){
int a[10] = {0}, idx = 0;
while(n){
a[++idx] = n % 9;
n /= 9;
}
for(int i = 1; i <= (idx + 1) / 2; i++)
if(a[i] != a[idx - i + 1])
return false;
for(int i = 1; i <= idx; i++)
if(a[i] % 2 == 0)
return false;
return true;
}
int main() {
cin >> n >> m;
for(int i = n; i <= m; i++)
if(is_huiwen(i))
res++;
cout << res << endl;
return 0;
}
第4题 收集宝石
用邻接矩阵g存储相冲的宝石,p存储已经选择的宝石,然后深搜枚举所有情况。
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 110;
int n, m;
bool g[N][N], p[N];
int res = 0;
void dfs(int u, int sum){
/*
剪枝:枚举到第u个宝石,选择宝石数为sum,即使把后面所有宝石(n-u)都选中,
都小于之前的最大值res,就满足剪枝条件。
*/
if(res > sum + n - u) return;
if(u > n){
res = max(res, sum);
return;
}
bool is_conflict = false;
for(int i = 1; i < u; i++){
if(p[i] && g[i][u]){
is_conflict = true;
break;
}
}
if(!is_conflict){
p[u] = true;
dfs(u + 1, sum + 1);
}
p[u] = false;
dfs(u + 1, sum);
}
int main() {
cin >> n >> m;
while(m--){
int a, b;
cin >> a >> b;
g[a][b] = g[b][a] = true;
}
dfs(1, 0);
cout << res <<endl;
return 0;
}
第5题 简易炸弹超人
解析:状态压缩DP
首先考虑如何安置炸弹合法,即一个炸弹安置后,其周围位置不能再安置炸弹。
如果炸弹安置在红色位置,那么周围4个绿色区域都会受到波及,不能再安置炸弹。而且炸弹爆炸后不能波及到同一个区域,因此黄色部分也不能安置炸弹。
炸弹安置要求:
- 只能在陆地上安置炸弹,不能在水域上安置炸弹;
- 某一行状态中不能有相邻的两个炸弹间隔小于2;
- 相邻三行,i、i-1、i-2不冲突;
- 当前位置与其左上、右上两个位置不冲突。
g[i]存储第i行水域情况。
第i行状态为s,二进制中1对应方格安置炸弹,0对应方格中不安置炸弹。
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int N = 110, M = 1 << 10;
int n, m;
int g[N];
int f[2][M][M];
vector<int> s;
bool check(int s){
return !(s & s >> 1 || s & s >> 2);
}
bool check2(int s){
return s & s >> 1;
}
int count(int i, int s){
int cnt = 0, flag = 0;
for(int j = 0; j < m; j++){
if(s >> j & 1){
flag = 1;
if(i - 1 >= 1) cnt++;
if(i + 1 <= n) cnt++;
if(j - 1 >= 0) cnt++;
if(j + 1 < m) cnt++;
}
}
return cnt + flag;
}
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 0; j < m; j++){
char ch;
cin >> ch;
if(ch == 'A') g[i] += 1 << j;
}
}
for(int i = 0; i < 1 << m; i++)
if(check(i)) s.push_back(i);
for(int i = 1; i <= n + 2; i++){
for(int j = 0; j < s.size(); j++)
for(int k = 0; k < s.size(); k++)
for(int u = 0; u < s.size(); u++){
// a当前行状态 b上一行状态 c上两行状态
int a = s[j], b = s[k], c = s[u];
if((a & b) || (a & c) || (b & c)) continue;
if((g[i] & a) || (g[i - 1] & b)) continue;
if(check2(b | c)) continue;
int cnt = i <= n ? count(i, a) : 0;
f[i & 1][j][k] = max(f[i & 1][j][k], f[i - 1 & 1][k][u] + cnt);
}
}
cout << f[n + 2 & 1][0][0] << endl;
return 0;
}