选择题
- 201720172017 年 101010 月 111 日是星期日,199919991999 年 101010 月 111 日是( )。
A. 星期三
B. 星期二
C. 星期日
D. 星期五
【解析】199919991999到201720172017年一共是181818年,18×365 %7=(18%7×365%7)%7=418\times 365 \ \% 7=(18\%7\times365\%7)\%7=418×365 %7=(18%7×365%7)%7=4,中间有555个闰年:2000,2004,2008,2012,20162000,2004,2008,2012,20162000,2004,2008,2012,2016,(4+5)%7=2(4+5)\%7=2(4+5)%7=2。也就是说199919991999
年 101010 月 111 日多加两天是星期日,那么199919991999 年 101010 月 111 日是星期五
。
- 甲、乙、丙三位同学选修课程,从 444 门课程中,甲选修 222 门,乙、丙各选修 333 门,则不同的选修方案共有( )种。
【解析】乘法原理:
- ①甲的方案数:C42=6C_4^2=6C42=6
- ②乙的方案数:C43=4C_4^3=4C43=4
- ③丙的方案数:C43=4C_4^3=4C43=4
乘法原理总的方案数为:6×4×4=966\times4\times4=966×4×4=96
- 设 GGG 是有 nnn 个结点、mmm 条边(n≤mn \le mn≤m)的连接图,必须删去 GGG 的( )条边,才能使得 GGG 变成一棵树。
【解析】nnn个结点的树一定有n−1n - 1n−1条边,必须从图中删除m−n+1m - n + 1m−n+1条边。
- 表达式 a*(b+c)*d 的后缀形式是( )。
【解析】套括号提取运算符。 ((a×(b+c))×d),将运算符提取到所在括号的右边:a b c + × d ×
- 若串
S="copyright"
,其子串的个数是( )。
【解析】
- 长度为0的子串=1
- 长度为1的子串=9
- …
一共有=1 + 9 + 8 + … + 1 =
46
- 十进制小数 13.37513.37513.375 对应的二进制数是( )。
【解析】整数部分除2取余逆序连接,小数部分乘2取整顺序连接。
- 设 AAA 和 BBB 是两个长为 nnn 的有序数组,现在需要将 AAA 和 BBB 合并成一个排好序的数组,任何以元素比较作为基本运算的归并算法在最坏情况下至少要做( )次比较。
【解析】在最坏情况下,BBB中除了最后一个数,每个数都会比较
2
次,一共2n - 2
次,最后一个数只比较1
次,所以结果为2n - 1
次
- 一家四口人,至少两个人生日属于同一月份的概率是( )。(假定每个人生日属于每个月份的概率相同且不同人之间相互独立)。
【解析】补集思想 至少两个人生日属于同一月份的概率 = 1 - 所有人的生日都是不同月份的概率。 所有人的生日都是不同月份的概率 = P124124=5596\frac{P_{12}^4}{12^4}= \frac{55}{96}124P124=9655。
答案:1−5596=41961-\frac{55}{96}=\frac{41}{96}1−9655=9641。
问题求解
- 一个人站在坐标(0,0)(0,0)(0,0)处,面朝 xxx 轴正方向。第一轮,他向前走 111 单位距离,然后右转;第二轮,他向前走 222 单位距离,然后右转;第三轮,他向前走 333 单位距离,然后右转……他一直这么走下去。请问第 201720172017 轮后,他的坐标是:(___ , ___)。
【解析】模拟找规律。
- 第①轮:x=1,y=0x=1, y=0x=1,y=0
- 第②轮:x=1,y=−2x=1, y=-2x=1,y=−2
- 第③轮:x=−2,y=−2x=-2, y=-2x=−2,y=−2
- 第④轮:x=−2,>y=2x=-2,> y=2x=−2,>y=2
- 第⑤轮:x=3,y=2x=3, y=2x=3,y=2
- 第⑥轮:x=3,y=−4x=3, y=-4x=3,y=−4
- 第⑦轮:x=−4,y=−4x=-4, y=-4x=−4,y=−4
- 第⑧轮:x=−4,y=4x=-4, y=4x=−4,y=4
- 第⑨轮:x=5,y=4x=5, y=4x=5,y=4 …
每4轮转一圈,第2017轮刚好是从第二象限水平向右走到第一象限,此时:
x=⌊20172⌋+1x= \lfloor \frac{2017}{2}\rfloor + 1x=⌊22017⌋+1,y=⌊20172⌋y= \lfloor \frac{2017}{2}\rfloory=⌊22017⌋
- 如下图所示,共有 131313个格子。对任何一个格子进行一次操作,会使得它自己以及与它上下左右相邻的格子中的数字改变(由 111 变 000,或由 $0 变 111)。现在要使得所有的格子中的数字都变为 000,至少需要_____次操作。
【解析】按照红绿蓝三个格子的顺序进行操作即可。
阅读程序写结果
#include <stdio.h>
int g(int m, int n, int x) {
int ans=0;
int i;
if(n == 1)
return 1;
for(i = x; i <= m / n; i++)
ans += g(m - i, n - 1, i);
return ans;
}
int main()
{
int t, m, n;
scanf("%d%d", &m, &n);
printf("%d", g(m, n, 0));
return 0;
}
输入:7 3
【解析】手动模拟递归调用。
答案:8
2.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string ch;
int a[200];
int b[200];
int n, i, t, res;
cin >> ch;
n = ch.length();
for(i = 0; i < 200; i++) b[i] = 0;
for(i = 1; i <= n ; i++) {
a[i] = ch[i-1] - '0';
b[i] = b[i-1] + a[i];
}
res = b[n];
t = 0;
for(i = n; i > 0; i--) {
if(a[i] == 0) t++;
if(b[i-1] + t < res) res = b[i-1] + t;
}
cout << res << endl;
return 0;
}
输入:100110101100110110101111000110011010110011011010111100011001101011001101101011110001
【解析】手动模拟。
a[]
记录输入的01序列。b[i]
表示序列前i
个数中1
的个数。
变量t
记录从序列从后向前(从n
到i
)中0
的个数。
变量res
为序列前i-1
个数中1的个数和从i
到n
中0的个数之和的最小值。
1001
101011001101101011110001
答案为:11
。
#include <iostream>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
int x = 1;
int y = 1;
int dx = 1;
int dy = 1;
int cnt = 0;
while(cnt != 2) {
cnt = 0;
x = x + dx;
y = y + dy;
if(x == 1 || x == n) {
++cnt;
dx = -dx;
}
if(y == 1 || y == m) {
++cnt;
dy = -dy;
}
}
cout << x << " " << y << endl;
return 0 ;
}
【解析】手动模拟,找规律
输入:4 3
n = 4, m = 3, dx = 1, dy = 1, x = 1, y = 1
x = 2, y = 2
x = 3, y = 3, dy = -1
x = 4, y = 2, dx = -1
x = 3, y = 1, dy = 1
x = 2, y = 2
x = 1, y = 3, dx = 1, dy = -1, cnt = 2
答案:1 3
输入:2017 1014
n = 2017, m = 1014, dx = 1, dy = 1, x = 1, y = 1
x = 2, y = 2
…
x = 1014, y = 1014, dy = -1
x = 1015, y = 1013
…
x = 2017, y = 1, dx = -1, dy = 1, cnt = 2
答案:2017 1
完善程序
(切割绳子)有 nn 条绳子,每条绳子的长度已知且均为正整数。绳子可以以任意正整数长度切割,但不可以连接。现在要从这些绳子中切割出m条长度相同的绳段,求绳段的最大长度是多少。
输入:第一行是一个不超过 100100100的正整数 nnn,第二行是 nnn 个不超过 10610^6106 的正整数,表示每条绳子的长度,第三行是一个不超过 10810^8108 的正整数 mmm。
输出 :绳段的最大长度,若无法切割,输出 Failed。
#include <iostream>
using namespace std;
int n, m, i, lbound, ubound, mid, count;
int len[100]; //绳子长度
int main()
{
cin >> n;
count = 0;
for (i = 0; i < n; i++) {
cin >> len[i];
①;
}
cin >> m;
if (②) {
cout << "Failed" << endl;
return 0;
}
lbound = 1 ;
ubound = 1000000 ;
while (③) {
mid = ④;
count =0 ;
for (i = 0; i < n; i++ )
⑤;
if (count < m)
ubound = mid - 1 ;
else
lbound = mid ;
}
cout << lbound << endl;
return 0;
}
【解析】二分搜索求切割出m条长度相同的绳段的最大长度。
空①,累加所有绳子的长度,答案:count+=len[i]
空②,如果绳子的总长度<m,那么不可能分割。答案:count<m
空③,二分搜索条件,lbound<ubound
空④,取中间值,注意,所有count>=m
的情况都可行,要左边区间的最大值,适用二分搜索模板2,答案:(lbound+ubound+1)/2
。
空⑤,累加分割的绳子数量,答案:count+=len[i]/m
。