问答题
问答题1:X86体系结构在保护模式下中有三种地址,请问一下那种说法是正确的?
A: 虚拟地址先经过分段机制映射到线性地址,然后线性地址通过分页机制映射到物理地址
B: 线性地址先经过分段机制映射到虚拟地址,然后虚拟地址通过分页机制映射到物理地址
C: 虚拟地址先经过分页机制映射到线性地址,然后线性地址通过分段机制映射到物理地址
D: 线性地址先经过分页机制映射到虚拟地址,然后虚拟地址通过分段机制映射到物理地址
提示:分段机制就是把虚拟地址空间中的虚拟内存组织成一些长度可变的称为段的内存块单元
分页机制把线性地址空间和物理地址空间分别划分为大小相同的块。这样的块称之为页。通过在线性地址空间的页与物理地址空间的页之间建立的映射,分页机制实现线性地址到物理地址的转换
问答题2: 以下说法不正确的是?
A: 进程调度中"可抢占"和"非抢占"两种方式,后者引起系统的开销更大
B: 每个进程都有自己的文件描述符表,所有进程共享同一打开文件表和v-node表
C: 基本的存储技术包括RAM,ROM,磁盘以及SSD,其中访问速度最慢的是磁盘,CPU的高速缓存一般是由RAM组成的
D: 多个进程竞争源出现了循环等待可能造成系统死锁
提示:可抢占式调度是严格保证任何时刻,让具有最高优先级的进程占有处理机运行,为被强占的进程保存现场,为占有处理机的进程恢复现场等,因此增加了处理机调度的时机,时间和空间开销自然会增大.
编程题
编程题1: 奇数位上都是奇数或者偶数位上都是偶数
给定一个长度不小于2的数组arr。 写一个函数调整arr,使arr中要么所有的偶数位上都是偶数,要么所有的奇数位上都是奇数上。 要求:如果数组长度为N,时间复杂度请达到O(N),额外空间复杂度请达到O(1),下标0,2,4,6…算作偶数位,下标1,3,5,7…算作奇数位,例如[1,2,3,4]调整为[2,1,4,3]即可
提示:在奇数位寻找偶数,在偶数位寻找奇数,然后交换即可
void oddInOddEvenInEven(std::vector<int>& arr, int len) {
long i = 0, j = 1;
while(i < len && j < len){
if((arr[i] % 2) == 0) {
i += 2;
continue;
}//偶数位上寻找非偶数
if((arr[j] % 2) != 0) {
j += 2;
continue;
}//奇数位上寻找非奇数
swap(arr[i], arr[j]);
}
}
编程题2:猴子分桃
老猴子辛苦了一辈子,给那群小猴子们留下了一大堆桃子。老猴子决定把这些桃子分给小猴子
第一个猴子来了,它把桃子分成五堆,五堆一样多,但还多出一个。它把剩下的一个留给老猴子,自己拿走其中的一堆
第二个猴子来了,它把桃子分成五堆,五堆一样多,但又多出一个。它把多出的一个留给老猴子,自己拿走其中的一堆
后来的小猴子都如此照办。最后剩下的桃子全部留给老猴子
这里有n只小猴子,请你写个程序计算一下在开始时至少有多少个桃子,以及最后老猴子最少能得到几个桃子
输入描述:输入包括多组测试数据。
每组测试数据包括一个整数n(1≤n≤20)
输入以0结束,该行不做处理。
输出描述:每组测试数据对应一行输出。
包括两个整数a,b 分别代表开始时最小需要的桃子数,和结束后老猴子最少能得到的桃子数
示例:
输入
5
1
0
输出
3121 1025
1 1
#include <iostream>
#include <string>
#include <math.h>
int main(){
int n;
while(std::cin >> n) {
if (n == 0) break;
long total = pow(5, n) - 4;
long left = pow(4, n) + n - 4;
std::cout << total << " " << left << std::endl;
}
return 0;
}
编程题3:计算美国节日
美国节日 和中国的节日不同,美国的节假日通常是选择某个月的第几个星期几这种形式,因此每一年的放假日期都不相同。具体规则如下:
- 1月1日:元旦
- 1月的第三个星期一:马丁·路德·金纪念日
- 2月的第三个星期一:总统节
- 5月的最后一个星期一:阵亡将士纪念日
- 7月4日:美国国庆
- 9月的第一个星期一:劳动节
- 11月的第四个星期四:感恩节
- 12月25日:圣诞节
现在给出一个年份,请你帮忙生成当年节日的日期
输入描述:输入包含多组数据,每组数据包含一个正整数year
输出描述:对应每一组数据,以“YYYY-MM-DD”格式输出当年所有的节日日期,每个日期占一行,每组数据之后输出一个空行作为分隔
输入 2014
输出
2014-01-01
2014-01-20
2014-02-17
2014-05-26
2014-07-04
2014-09-01
2014-11-27
2014-12-25
#include <iostream>
#include <cstdio>
// 根据 年-月-日 通过蔡勒公式计算当前星期几
// 1: 星期一 ... 7: 星期日
int day_of_week(int year, int month, int day){
if (month == 1 || month == 2){
month += 12;
year -= 1;
}
int century = year / 100;
year %= 100;
int week = year + (year / 4) + (century / 4) - 2 * century +
26 * (month + 1) / 10 + day -1;
week = (week % 7 + 7) % 7;
if (week == 0){
week = 7;
}
return week;
}
int day_of_demand(int year, int month, int count, int d_of_week){
int week = day_of_week(year, month, 1);
//求出1号星期数
// 1 + 7(n - 1) + (所求星期数 + 7 - 1号星期数) % 7
int day = 1 + (count - 1) * 7 + (7 + d_of_week - week) % 7;
return day;
}
// 元旦
void new_year_day(int year){
printf("%d-01-01\n", year);
}
// 马丁·路德·金纪念日(1月的第三个星期一)
void martin_luther_king_day(int year){
printf("%d-01-%02d\n", year, day_of_demand(year, 1, 3, 1));
}
// 总统日(2月的第三个星期一)
void president_day(int year){
printf("%d-02-%02d\n", year, day_of_demand(year, 2, 3, 1));
}
// 阵亡将士纪念日(5月的最后一个星期一)
void memorial_day(int year){
// 从 6 月往前数
int week = day_of_week(year, 6, 1);
// 星期一的话,从 31 号往前数 6 天,否则,数 week - 2 天
int day = 31 - ((week == 1) ? 6 : (week - 2));
printf("%d-05-%02d\n", year, day);
}
// 国庆
void independence_day(int year){
printf("%d-07-04\n", year);
}
// 劳动节(9月的第一个星期一)
void labor_day(int year){
printf("%d-09-%02d\n", year, day_of_demand(year, 9, 1, 1));
}
// 感恩节(11月的第四个星期四)
void thanks_giving_day(int year){
printf("%d-11-%02d\n", year, day_of_demand(year, 11, 4, 4));
}
// 圣诞节
void christmas(int year){
printf("%d-12-25\n", year);
}
// 美国节日
void holiday_of_usa(int year){
new_year_day(year);
martin_luther_king_day(year);
president_day(year);
memorial_day(year);
independence_day(year);
labor_day(year);
thanks_giving_day(year);
christmas(year);
}
int main(){
int year;
while (std::cin >> year){
holiday_of_usa(year);
putchar('\n');
}
}
编程题4: 分解因数
所谓因子分解,就是把给定的正整数a,分解成若干个素数的乘积,即 a = a1 × a2 × a3 × ... × an
,并且 1 < a1 ≤ a2 ≤ a3 ≤ ... ≤ an
其中a1、a2、...、an
均为素数。 先给出一个整数a,请输出分解后的因子
输入描述:输入包含多组数据,每组数据包含一个正整数 a(2≤a)
输出描述:对应每组数据,以a = a1 * a2 * a3...
的形式输出因式分解后的结果
输入
10 18
输出
10 = 2 * 5
18 = 2 * 3 * 3
看到短除法后,我们很清楚的知道,要想求出它的每一个质因数,我们需要用质数去试除。90能被2整除,那就拿商继续除以2,除不尽就换3,一直到除到质数为止。基础代码框架类似判断质数,只是被判断的数字在过程中不断被除,最终循环结束的时候,那个被处理过的数字,就是最后一个质因数。以下代码注释以90为例
#include <cstdio>
#include <cmath>
#include <iostream>
int main(){
unsigned int n;
while (std::cin >> n){
printf("%d =", n);
//输出90 =
for (unsigned i = 2; i <= std::sqrt(n); i++){
//反复除同一个数,直到除不尽,排除刚好是该数的n次方的情况
while (n % i == 0 && n != i) {
//第一次打印 2 *,第二次打印两个 3 *
printf(" %u *", i);
n /= i; //能整除就修改n的值
}
}
//跳出后,n已经是处理过的一个质数,就是最后一个质因数:5
printf(" %d\n", n);
}
return 0;
}