[关闭]
@P2Oileen 2017-08-05T03:19:17.000000Z 字数 4183 阅读 1843

Homework 1

标★的题目为选做题,仅供学有余力的同学尝试,并且评分标准也更严格。请先做完不标★的题目,再尝试做标一个★的题目,再尝试做更多★的题目。

本次作业总分:30+4.0


Introduction


★简答题(0.4分)

  1. NOI2018是第几届NOI? 35
  2. IOI2018是第几届IOI? 30
  3. NOIP的全称是什么? 全国青少年信息学奥林匹克联赛
  4. 本次作业的提交方式是?提交的截止时间是?
    email提交,8.4晚23:33之前(qwq)

语言基础

在这些题目中,我们只考虑通常的NOI Linux比赛环境:计算机的字长为32位,有符号整数类型采用补码(2's complement)方法表示。并且,我们暂且不考虑C++标准的要求,只考虑实际编译器的效果。


整数类型(6.2分)

对于下面的整数类型,指出其宽度(以二进制位计)、能表示的最小数、能表示的最大数。并指出类型描述的哪些词可以被省略。

例子:signed int,是整数类型,宽度为32,能表示的最小数为-2147483648,能表示的最大数为2147483647,signed可被省略。
(注:C++标准对此宽度的限制仅为“至少为16”,但通常的实践中都是至少为32,在上述的环境中为32,所以本题中我们先不管C++标准对于宽度的限制)

  1. unsigned short int
  2. short short int
  3. int
  4. unsigned int
  5. long int signed
  6. int long unsigned long
  7. ★signed char
  8. ★double
类型 宽度 最小数 最大数 省略后
unsigned short int 16 0 65535 unsigned short
short short int 16 -32768 32767 short
int 32 -2147483648 2147483647 int
unsigned int 32 0 4294967295 unsigned int
long int signed 64 -9223372036854775808 9,223,372,036,854,775,807 long long
int long unsigned long 64 0 18,446,744,073,709,551,615 unsigned long long
signed char 8 -128 127 char
double 64 1.79769e+308 2.22507e-308 double

★看结果写输入(0.4分)

★(1)

  1. #include <cstdio>
  2. int main()
  3. {
  4. unsigned int a = 233;
  5. scanf("%u", &a);
  6. if(a == -a){
  7. printf("OK\n");
  8. return 0;
  9. }
  10. else return 1;
  11. }

输入什么会输出OK?请给出两个答案(如果你只能想出一个就写一个),输入中不能有任何空白字符。
0 2147483648

★★(2)

  1. #include <cstdio>
  2. int main()
  3. {
  4. float a = 2.33;
  5. scanf("%f", &a);
  6. if(a != a){
  7. printf("OK\n");
  8. return 0;
  9. }
  10. else return 1;
  11. }

输入什么会输出OK?请给出两个答案(如果你只能想出一个就写一个),输入中不能有任何空白字符。


★标准函数(2.0分)

你最好能够理解以下每个函数的功能。请简单写下以下每个函数的功能,如果你认为你已经熟练掌握则不必写。

这道题为选做题的原因并不是因为难度,而是题太多了……

  1. <cmath>
  2. sin log atan2 fmod remainder
  3. <cctype>
  4. isdigit
  5. <cstdlib>
  6. atoi strtoul
  7. <cstring>
  8. strcpy strncpy strcat strncat strlen strcmp strncmp strstr
  9. memcmp memset memcpy memmove
库 函数 功能
cmath sin 得到角对应的弧度
log 求以e为底的对数,可以用换底公式得到以其它为底的对数
atan2 求tan的反函数,范围从-pi~pi
fmod 浮点数取余
remainder 除法运算的有符号余数
cctype isdigit 检查c是否为0-9
cstdlib atoi 将字符串转换为整型
strtoul 将字符串转换为无符号整型
cstring strcpy 复制字符串
strncpy 把指定长度和首指针的字符串复制了
strcat 将两个字符串首尾相连
strncat 将第二个字符串前n位连到第一个后面
strlen 求字符串长度
strcmp 比较字符串大小
strncmp 比较两字符串的n个字符
strstr 判断一个串是否为另一个串的子串
memcmp 比较两块内存区域的前n个字节
memset 将一块内存区域刷成一个ascii值
memcpy 将一块内存拷贝到另一个地方
memmove 保证源串在被覆盖前将重叠区域的字节拷到目标区域中

★★★这段程序怎么了?(0.1分)

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <ctime>
  4. struct Test
  5. {
  6. char a; int b; short c;
  7. };
  8. void test()
  9. {
  10. Test t = {
  11. .a = 'a', .b = 2333, .c = 666
  12. };
  13. Test u =
  14. {
  15. .a = 'a', .b = 2333, .c = 666
  16. };
  17. if(memcmp(&t, &u, sizeof(Test)) == 0)
  18. printf("t == u\n");
  19. else printf("t != u\n");
  20. }
  21. void magic()
  22. {
  23. int a[6] = {2, 3, 3, 6, 6, 6};
  24. printf("magic %d\n", a[time(0) % 6]);
  25. }
  26. int main() {
  27. for(int i = 0; i < 3; i++)
  28. {
  29. test();
  30. magic();
  31. }
  32. return 0;
  33. }

在不同的编译器、编译选项下运行都会得到不同的结果,并且会经常出现t != u的输出,这是为什么呢?难道是因为定义t和u的时候一个大括号换行了而另一个没有???

我觉得这个magic肯定不是看着玩的……所以大概和它有关233333


Big O notation


选择题(10.5分)

d1.
g2.
b2.
b3.
d4.
e5.
e6.
i7.
d8.
d10.
d9. ★
b10. ★
d10. ★
e10. ★
i10. ★

可供选择的选项:

A.

B. ,但不是A

C. ,但不是A,也不是B

D. ,但不是以上任何选项

E. ,但不是以上任何选项

F. ,但不是以上任何选项

G. ,但不是以上任何选项

H. ,但不是以上任何选项

I. ,但不是以上任何选项

J. ,但不是以上任何选项

K. ,但不是以上任何选项

L. ,但不是以上任何选项

M. 不是以上任何选项


Complexity


判断复杂度(11.2分)

判断下列代码的时间复杂度。请用大记号,或用你认为最紧的大记号来表示。本题中假定每个变量的取值范围不受计算机字长限制。

(1) O(n^2)

  1. for(i = 1; i <= n; i++)
  2. for(j = 1; j <= i; j++)
  3. ans++;

(2) O(n^3)

  1. for(i = 1; i <= n; i++)
  2. for(j = 1; j <= i; j++)
  3. for(k = i; k <= n; k++)
  4. ans++;

(3)O(logn)

  1. for(i = 1; i <= n; i *= 2)
  2. ans++;

(4)O(nlogn)

  1. for(i = 1; i <= n; i++)
  2. for(int j = 1; j <= i; j *= 2)
  3. ans++;

(5)O(lognlogn)

  1. for(i = 1; i <= n; i *= 2)
  2. for(int j = 1; j <= i; j *= 2)
  3. ans++;

(6)O(nlogn)

  1. for(i = 1; i <= n; i++)
  2. for(int j = 1; j <= n; j += i)
  3. ans++;

(7)O(n)

  1. for(i = 1; i <= n; i *= 2)
  2. for(int j = 1; j <= n; j += i)
  3. ans++;

(8)O(2^x)

  1. void f(int x) {
  2. if(x >= 3) {
  3. f(x - 1);
  4. f(x - 2);
  5. ans++;
  6. }
  7. }
  8. f(n);

(9)O(x)

  1. void f(int x) {
  2. if(x >= 2) {
  3. f(x / 2);
  4. f(x / 2);
  5. ans++;
  6. }
  7. }
  8. f(n);

(10)O(x^2)

  1. void f(int x) {
  2. if(x >= 2) {
  3. f(x / 2);
  4. f(x / 2);
  5. for(int i = 1; i <= x; i++)
  6. ans++;
  7. }
  8. }
  9. f(n);

(11)O(x^2)

  1. void f(int x) {
  2. if(x >= 2) {
  3. ans++;
  4. for(int i = 1; i < x; i++)
  5. f(i);
  6. }
  7. }
  8. f(n);

★(12)

  1. void f(int n, string s) {
  2. ans++;
  3. if(s.length() < n)
  4. for(char c = '0'; c < '0' + n; c++)
  5. if(s.find(c) == string::npos)
  6. f(n, s + c);
  7. }
  8. f(n, "");

★(13)O(2^x)

  1. void f(x) {
  2. if(x >= 4) {
  3. f(x - 1);
  4. f(x - 3);
  5. ans++;
  6. }
  7. }
  8. f(n);

提示:实在判断不准的,可做实验试试。


判断题(3.2分)

对于每道题,回答“对”或“错”或“目前无法确定”。

对1. 如果存在一个NP-完全问题能被确定图灵机在多项式时间内解决,则所有NP问题都能被这样解决。
错2. 任何NP问题都不是P问题。
对3. 存在一个问题,既是NP问题,又是NP-难问题。
错4. ★存在一个问题,既是P问题,又是NP-完全问题。
目前无法确定5. ★如果存在一个NP-难问题能被确定图灵机在多项式时间内解决,则所有NP-完全问题都能被这样解决。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注