NOIP 2010初賽試題
(普及組 C++語言 )
●● 全部試題答案均要求寫在答卷紙上,寫在試卷紙上一律無效 ●●
一、單項選擇題(共20題,每題1.5分,共計30分。每題有且僅有一個正確選項。)
1.2E+03表示( )。
A. 2.03 B.5 C. 8 D. 2000
2.一個字節(byte)由( )個二進制位組成。
A. 8 B.16 C. 32 D.以上都有可能
3.以下邏輯表達式的值恆為真的是( )。
A. P∨(¬P∧Q)∨(¬P∧¬Q) B. Q∨(¬P∧Q)∨(P∧¬Q)
C. P∨Q∨(P∧¬Q)∨(¬P∧Q) D. P∨¬Q∨(P∧¬Q)∨(¬P∧¬Q)
4.Linux下可執行文件的默認擴展名為( )。
A. exe B. com C. dll D.以上都不是
5.如果樹根算第1層,那麼一棵n層的二叉樹最多有( )個結點。
A. 2n-1 B. 2n C. 2n+1 D. 2n+1
6.提出“存儲程序”的計算機工作原理的是( )。
A.克勞德·香農 B.戈登·摩爾 C.查爾斯·巴比奇 D.馮·諾依曼
7.設X、Y、Z分別代表三進制下的一位數字,若等式XY + ZX = XYX在三進制下成立,那麼同樣在三進制下,等式XY * ZX =( )也成立。
A. YXZ B. ZXY C. XYZ D. XZY
8.Pascal語言、C語言和C++語言都屬於( )。
A.面嚮對象語言 B.腳本語言 C.解釋性語言 D.編譯性語言
9.前綴表達式“+ 3 * 2 + 5 12”的值是( )。
A. 23 B.25 C. 37 D. 65
10.主存儲器的存取速度比中央處理器(CPU)的工作速度慢得多,從而使得後者的效率受到影響。而根據局部性原理,CPU所訪問的存儲單元通常都趨於聚集在一個較小的連續區域中。於是,為了提高系統整體的執行效率,在CPU中引入了( )。
A.寄存器 B.高速緩存 C.閃存 D.外存
11.一個字長為8位的整數的補碼是11111001,則它的原碼是( )。
A.00000111 B.01111001 C. 11111001 D.10000111
12.基於比較的排序時間複雜度的下限是( ),其中n表示待排序的元素個數。
A.Θ(n) B.Θ(n log n) C.Θ(log n) D.Θ(n2)
13.一個自然數在十進制下有n位,則它在二進制下的位數與( )最接近。
A. 5n B. n*log210 C. 10*log2n D. 10nlog2n
14.在下列HTML語句中,可以正確產生一個指向NOI官方網站的超鏈接的是( )。
A.
B.
C.
D.
15.元素R1、R2、R3、R4、R5入棧的順序為R1、R2、R3、R4、R5。如果第1個出棧的是R3,那麼第5個出棧的不可能是( )。
A. R1 B. R2 C. R4 D. R5
16.雙向鏈表中有兩個指針域llink和rlink,分別指向該結點的前驅及後繼。設p指向鏈表中的一個結點,它的左右結點均非空。現要求刪除結點p,則下面語句序列中錯誤的是( )。
A. p->rlink->llink = p->rlink;
p->llink->rlink = p->llink; delete p;
B.p->llink->rlink = p->rlink;
p->rlink->llink = p->llink;delete p;
C.p->rlink->llink = p->llink;
p->rlink->llink->rlink = p->rlink;delete p;
D.p->llink->rlink = p->rlink;
p->llink->rlink->llink = p->llink;delete p;
17.一棵二叉樹的前序遍歷序列是ABCDEFG,後序遍歷序列是CBFEGDA,則根結點的左子樹的結點個數可能是( )。
A. 2 B.3 C. 4 D. 5
18.關於拓撲排序,下面說法正確的是( )。
A.所有連通的有向圖都可以實現拓撲排序
B.對同一個圖而言,拓撲排序的結果是唯一的
C.拓撲排序中入度為0的結點總會排在入度大於0的結點的前面
D.拓撲排序結果序列中的第一個結點一定是入度為0的點
19.完全二叉樹的順序存儲方案,是指將完全二叉樹的結點從上至下、從左至右依次存放到一個順序結構的數組中。假定根結點存放在數組的1號位置,則第k號結點的父結點如果存在的話,應當存放在數組的( )號位置。
A. 2k B. 2k+1 C. k/2下取整 D. (k+1)/2下取整
20.全國青少年信息學奧林匹克系列活動的主辦單位是( )。
A.教育部 B.科技部 C.共青團中央 D.中國計算機學會
二、問題求解(共2題,每題5分,共計10分)
1.LZW編碼是一種自適應詞典編碼。在編碼的過程中,開始時只有一部基礎構造元素的編碼詞典,如果在編碼的過程中遇到一個新的詞條,則該詞條及一個新的編碼會被追加到詞典中,並用於後繼信息的編碼。
舉例說明,考慮一個待編碼的信息串:"xyx yy yy xyx"。初始詞典只有3個條目,第一個為x,編碼為1;第二個為y,編碼為2;第三個為空格,編碼為3;於是串"xyx"的編碼為1-2-1(其中-為編碼分隔符),加上後面的一個空格就是1-2-1-3。但由於有了一個空格,我們就知道前面的"xyx"是一個單詞,而由於該單詞沒有在詞典中,我們就可以自適應的把這個詞條添加到詞典裡,編碼為4,然後按照新的詞典對後繼信息進行編碼,以此類推。於是,最後得到編碼:1-2-1-3-2-2-3-5-3-4。
現在已知初始詞典的3個條目如上述,則信息串"yyxy xx yyxy xyx xx xyx"的編碼是_________。
2.隊列快照是指在某一時刻隊列中的元素組成的有序序列。例如,當元素1、2、3入隊,元素1出隊後,此刻的隊列快照是"2 3"。當元素2、3也出隊後,隊列快照是"",即為空。現有3個正整數元素依次入隊、出隊。已知它們的和為8,則共有_________種可能的不同的隊列快照(不同隊列的相同快照只計一次)。例如,"5 1"、"4 2 2"、""都是可能的隊列快照;而"7"不是可能的隊列快照,因為剩下的2個正整數的和不可能是1。
三、閱讀程序寫結果(共4題,每題8分,其中第4題(1)、(2)各4分,共計32分)
1.
#include <iostream>
using namespace std;
void swap(int & a, int & b)
{
int t;
t = a;
a = b;
b = t;
}
int main()
{
int a1, a2, a3, x;
cin>>a1>>a2>>a3;
if (a1 > a2)
swap(a1, a2);
if (a2 > a3)
swap(a2, a3);
if (a1 > a2)
swap(a1, a2);
cin>>x;
if (x < a2)
if (x < a1)
cout<
else
cout<
else
if (x < a3)
cout<
else
cout<
return 0;
}
輸入:
91 2 20
77
輸出:_________
2.
#include <iostream>
using namespace std;
int rSum(int j)
{
int sum = 0;
while (j != 0) {
sum = sum * 10 + (j % 10);
j = j / 10;
}
return sum;
}
int main()
{
int n, m, i;
cin>>n>>m;
for (i = n; i < m; i++)
if (i == rSum(i))
cout<
return 0;
}
輸入:90 120
輸出:_________
3.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
char m1, m2;
int i;
getline(cin, s);
m1 = ' ';
m2 = ' ';
for (i = 0; i < s.length(); i++)
if (s[i] > m1) {
m2 = m1;
m1 = s[i];
}
else if (s[i] > m2)
m2 = s[i];
cout<
return 0;
}
輸入:Expo 2010ShanghaiChina
輸出:_________
提示:
字符
空格
'0'
'A'
'a'
ASCII碼
32
48
65
97
4.
#include <iostream>
using namespace std;
const int NUM = 5;
int r(int n)
{
int i;
if (n <= NUM)
return n;
for (i = 1; i <= NUM; i++)
if (r(n - i) < 0)
return i;
return -1;
}
int main()
{
int n;
cin>>n;
cout<
return 0;
}
(1)
輸入:7
輸出:_________(4分)
(2)
輸入:16
輸出:_________(4分)
四、完善程序(前4空,每空2.5分,後6空,每空3分,共計28分)
1.(哥德巴赫猜想)哥德巴赫猜想是指,任一大於2的偶數都可寫成兩個質數之和。迄今為止,這仍然是一個著名的世界難題,被譽為數學王冠上的明珠。試編寫程序,驗證任一大於2且不超過n的偶數都能寫成兩個質數之和。
#include <iostream>
using namespace std;
int main()
{
const int SIZE = 1000;
int n, r, p[SIZE], i, j, k, ans;
bool tmp;
cin>>n;
r = 1;
p[1] = 2;
for (i = 3; i <= n; i++) {
① ;
for (j = 1; j <= r; j++)
if (i % ② == 0) {
tmp = false;
break;
}
if (tmp) {
r++;
③ ;
}
}
ans = 0;
for (i = 2; i <= n / 2; i++) {
tmp = false;
for (j = 1; j <= r; j++)
for (k = j; k <= r; k++)
if (i + i == ④ ) {
tmp = true;
break;
}
if (tmp)
ans++;
}
cout<
return 0;
}
若輸入n為2010,則輸出 ⑤ 時表示驗證成功,即大於2且不超過2010的偶數都滿足哥德巴赫猜想。
2.(過河問題)在一個月黑風高的夜晚,有一群人在河的右岸,想通過唯一的一根獨木橋走到河的左岸。在這伸手不見五指的黑夜裡,過橋時必須藉助燈光來照明,很不幸的是,他們只有一盞燈。另外,獨木橋上最多承受兩個人同時經過,否則將會坍塌。每個人單獨過橋都需要一定的時間,不同的人需要的時間可能不同。兩個人一起過橋時,由於只有一盞燈,所以需要的時間是較慢的那個人單獨過橋時所花的時間。現輸入n(2≤n<100)和這n個人單獨過橋時需要的時間,請計算總共最少需要多少時間,他們才能全部到達河的左岸。
例如,有3個人甲、乙、丙,他們單獨過橋的時間分別為1、2、4,則總共最少需要的時間為7。具體方法是:甲、乙一起過橋到河的左岸,甲單獨回到河的右岸將燈帶回,然後甲、丙再一起過橋到河的左岸,總時間為2+1+4=7。
#include <iostream>
using namespace std;
const int SIZE = 100;
const int INFINITY = 10000;
const bool LEFT = true;
const bool RIGHT = false;
const bool LEFT_TO_RIGHT = true;
const bool RIGHT_TO_LEFT = false;
int n, hour[SIZE];
bool pos[SIZE];
int max(int a, int b)
{
if (a > b)
return a;
else
return b;
}
int go(bool stage)
{
int i, j, num, tmp, ans;
if (stage == RIGHT_TO_LEFT) {
num = 0;
ans = 0;
for (i = 1; i <= n; i++)
if (pos[i] == RIGHT) {
num++;
if (hour[i] > ans)
ans = hour[i];
}
if ( ① )
return ans;
ans = INFINITY;
for (i = 1; i <= n - 1; i++)
if (pos[i] == RIGHT)
for (j = i + 1; j <= n; j++)
if (pos[j] == RIGHT) {
pos[i] = LEFT;
pos[j] = LEFT;
tmp = max(hour[i], hour[j]) + ② ;
if (tmp < ans)
ans = tmp;
pos[i] = RIGHT;
pos[j] = RIGHT;
}
return ans;
}
if (stage == LEFT_TO_RIGHT) {
ans = INFINITY;
for (i = 1; i <= n; i++)
if ( ③ ) {
pos[i] = RIGHT;
tmp = ④ ;
if (tmp < ans)
ans = tmp;
⑤ ;
}
return ans;
}
return 0;
}
int main()
{
int i;
cin>>n;
for (i = 1; i <=n; i++) {
cin>>hour[i];
pos[i] = RIGHT;
}
cout<
return 0;
}
NOIP 2010試題與解題報告
NOIP 2010初賽試題
(普及組 C++語言 )
●● 全部試題答案均要求寫在答卷紙上,寫在試卷紙上一律無效 ●●
一、單項選擇題(共20題,每題1.5分,共計30分。每題有且僅有一個正確選項。)
1.2E+03表示( )。
A. 2.03 B.5 C. 8 D. 2000
2.一個字節(byte)由( )個二進制位組成。
A. 8 B.16 C. 32 D.以上都有可能
3.以下邏輯表達式的值恆為真的是( )。
A. P∨(¬P∧Q)∨(¬P∧¬Q) B. Q∨(¬P∧Q)∨(P∧¬Q)
C. P∨Q∨(P∧¬Q)∨(¬P∧Q) D. P∨¬Q∨(P∧¬Q)∨(¬P∧¬Q)
4.Linux下可執行文件的默認擴展名為( )。
A. exe B. com C. dll D.以上都不是
5.如果樹根算第1層,那麼一棵n層的二叉樹最多有( )個結點。
A. 2n-1 B. 2n C. 2n+1 D. 2n+1
6.提出“存儲程序”的計算機工作原理的是( )。
A.克勞德·香農 B.戈登·摩爾 C.查爾斯·巴比奇 D.馮·諾依曼
7.設X、Y、Z分別代表三進制下的一位數字,若等式XY + ZX = XYX在三進制下成立,那麼同樣在三進制下,等式XY * ZX =( )也成立。
A. YXZ B. ZXY C. XYZ D. XZY
8.Pascal語言、C語言和C++語言都屬於( )。
A.面嚮對象語言 B.腳本語言 C.解釋性語言 D.編譯性語言
9.前綴表達式“+ 3 * 2 + 5 12”的值是( )。
A. 23 B.25 C. 37 D. 65
10.主存儲器的存取速度比中央處理器(CPU)的工作速度慢得多,從而使得後者的效率受到影響。而根據局部性原理,CPU所訪問的存儲單元通常都趨於聚集在一個較小的連續區域中。於是,為了提高系統整體的執行效率,在CPU中引入了( )。
A.寄存器 B.高速緩存 C.閃存 D.外存
11.一個字長為8位的整數的補碼是11111001,則它的原碼是( )。
A.00000111 B.01111001 C. 11111001 D.10000111
12.基於比較的排序時間複雜度的下限是( ),其中n表示待排序的元素個數。
A.Θ(n) B.Θ(n log n) C.Θ(log n) D.Θ(n2)
13.一個自然數在十進制下有n位,則它在二進制下的位數與( )最接近。
A. 5n B. n*log210 C. 10*log2n D. 10nlog2n
14.在下列HTML語句中,可以正確產生一個指向NOI官方網站的超鏈接的是( )。
A.
B.
C.
D.
15.元素R1、R2、R3、R4、R5入棧的順序為R1、R2、R3、R4、R5。如果第1個出棧的是R3,那麼第5個出棧的不可能是( )。
A. R1 B. R2 C. R4 D. R5
16.雙向鏈表中有兩個指針域llink和rlink,分別指向該結點的前驅及後繼。設p指向鏈表中的一個結點,它的左右結點均非空。現要求刪除結點p,則下面語句序列中錯誤的是( )。
A. p->rlink->llink = p->rlink;
p->llink->rlink = p->llink; delete p;
B.p->llink->rlink = p->rlink;
p->rlink->llink = p->llink;delete p;
C.p->rlink->llink = p->llink;
p->rlink->llink->rlink = p->rlink;delete p;
D.p->llink->rlink = p->rlink;
p->llink->rlink->llink = p->llink;delete p;
17.一棵二叉樹的前序遍歷序列是ABCDEFG,後序遍歷序列是CBFEGDA,則根結點的左子樹的結點個數可能是( )。
A. 2 B.3 C. 4 D. 5
18.關於拓撲排序,下面說法正確的是( )。
A.所有連通的有向圖都可以實現拓撲排序
B.對同一個圖而言,拓撲排序的結果是唯一的
C.拓撲排序中入度為0的結點總會排在入度大於0的結點的前面
D.拓撲排序結果序列中的第一個結點一定是入度為0的點
19.完全二叉樹的順序存儲方案,是指將完全二叉樹的結點從上至下、從左至右依次存放到一個順序結構的數組中。假定根結點存放在數組的1號位置,則第k號結點的父結點如果存在的話,應當存放在數組的( )號位置。
A. 2k B. 2k+1 C. k/2下取整 D. (k+1)/2下取整
20.全國青少年信息學奧林匹克系列活動的主辦單位是( )。
A.教育部 B.科技部 C.共青團中央 D.中國計算機學會
二、問題求解(共2題,每題5分,共計10分)
1.LZW編碼是一種自適應詞典編碼。在編碼的過程中,開始時只有一部基礎構造元素的編碼詞典,如果在編碼的過程中遇到一個新的詞條,則該詞條及一個新的編碼會被追加到詞典中,並用於後繼信息的編碼。
舉例說明,考慮一個待編碼的信息串:"xyx yy yy xyx"。初始詞典只有3個條目,第一個為x,編碼為1;第二個為y,編碼為2;第三個為空格,編碼為3;於是串"xyx"的編碼為1-2-1(其中-為編碼分隔符),加上後面的一個空格就是1-2-1-3。但由於有了一個空格,我們就知道前面的"xyx"是一個單詞,而由於該單詞沒有在詞典中,我們就可以自適應的把這個詞條添加到詞典裡,編碼為4,然後按照新的詞典對後繼信息進行編碼,以此類推。於是,最後得到編碼:1-2-1-3-2-2-3-5-3-4。
現在已知初始詞典的3個條目如上述,則信息串"yyxy xx yyxy xyx xx xyx"的編碼是_________。
2.隊列快照是指在某一時刻隊列中的元素組成的有序序列。例如,當元素1、2、3入隊,元素1出隊後,此刻的隊列快照是"2 3"。當元素2、3也出隊後,隊列快照是"",即為空。現有3個正整數元素依次入隊、出隊。已知它們的和為8,則共有_________種可能的不同的隊列快照(不同隊列的相同快照只計一次)。例如,"5 1"、"4 2 2"、""都是可能的隊列快照;而"7"不是可能的隊列快照,因為剩下的2個正整數的和不可能是1。
三、閱讀程序寫結果(共4題,每題8分,其中第4題(1)、(2)各4分,共計32分)
1.
#include <iostream>
using namespace std;
void swap(int & a, int & b)
{
int t;
t = a;
a = b;
b = t;
}
int main()
{
int a1, a2, a3, x;
cin>>a1>>a2>>a3;
if (a1 > a2)
swap(a1, a2);
if (a2 > a3)
swap(a2, a3);
if (a1 > a2)
swap(a1, a2);
cin>>x;
if (x < a2)
if (x < a1)
cout<
else
cout<
else
if (x < a3)
cout<
else
cout<
return 0;
}
輸入:
91 2 20
77
輸出:_________
2.
#include <iostream>
using namespace std;
int rSum(int j)
{
int sum = 0;
while (j != 0) {
sum = sum * 10 + (j % 10);
j = j / 10;
}
return sum;
}
int main()
{
int n, m, i;
cin>>n>>m;
for (i = n; i < m; i++)
if (i == rSum(i))
cout<
return 0;
}
輸入:90 120
輸出:_________
3.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
char m1, m2;
int i;
getline(cin, s);
m1 = ' ';
m2 = ' ';
for (i = 0; i < s.length(); i++)
if (s[i] > m1) {
m2 = m1;
m1 = s[i];
}
else if (s[i] > m2)
m2 = s[i];
cout<
return 0;
}
輸入:Expo 2010ShanghaiChina
輸出:_________
提示:
字符
空格
'0'
'A'
'a'
ASCII碼
32
48
65
97
4.
#include <iostream>
using namespace std;
const int NUM = 5;
int r(int n)
{
int i;
if (n <= NUM)
return n;
for (i = 1; i <= NUM; i++)
if (r(n - i) < 0)
return i;
return -1;
}
int main()
{
int n;
cin>>n;
cout<
return 0;
}
(1)
輸入:7
輸出:_________(4分)
(2)
輸入:16
輸出:_________(4分)
四、完善程序(前4空,每空2.5分,後6空,每空3分,共計28分)
1.(哥德巴赫猜想)哥德巴赫猜想是指,任一大於2的偶數都可寫成兩個質數之和。迄今為止,這仍然是一個著名的世界難題,被譽為數學王冠上的明珠。試編寫程序,驗證任一大於2且不超過n的偶數都能寫成兩個質數之和。
#include <iostream>
using namespace std;
int main()
{
const int SIZE = 1000;
int n, r, p[SIZE], i, j, k, ans;
bool tmp;
cin>>n;
r = 1;
p[1] = 2;
for (i = 3; i <= n; i++) {
① ;
for (j = 1; j <= r; j++)
if (i % ② == 0) {
tmp = false;
break;
}
if (tmp) {
r++;
③ ;
}
}
ans = 0;
for (i = 2; i <= n / 2; i++) {
tmp = false;
for (j = 1; j <= r; j++)
for (k = j; k <= r; k++)
if (i + i == ④ ) {
tmp = true;
break;
}
if (tmp)
ans++;
}
cout<
return 0;
}
若輸入n為2010,則輸出 ⑤ 時表示驗證成功,即大於2且不超過2010的偶數都滿足哥德巴赫猜想。
2.(過河問題)在一個月黑風高的夜晚,有一群人在河的右岸,想通過唯一的一根獨木橋走到河的左岸。在這伸手不見五指的黑夜裡,過橋時必須藉助燈光來照明,很不幸的是,他們只有一盞燈。另外,獨木橋上最多承受兩個人同時經過,否則將會坍塌。每個人單獨過橋都需要一定的時間,不同的人需要的時間可能不同。兩個人一起過橋時,由於只有一盞燈,所以需要的時間是較慢的那個人單獨過橋時所花的時間。現輸入n(2≤n<100)和這n個人單獨過橋時需要的時間,請計算總共最少需要多少時間,他們才能全部到達河的左岸。
例如,有3個人甲、乙、丙,他們單獨過橋的時間分別為1、2、4,則總共最少需要的時間為7。具體方法是:甲、乙一起過橋到河的左岸,甲單獨回到河的右岸將燈帶回,然後甲、丙再一起過橋到河的左岸,總時間為2+1+4=7。
#include <iostream>
using namespace std;
const int SIZE = 100;
const int INFINITY = 10000;
const bool LEFT = true;
const bool RIGHT = false;
const bool LEFT_TO_RIGHT = true;
const bool RIGHT_TO_LEFT = false;
int n, hour[SIZE];
bool pos[SIZE];
int max(int a, int b)
{
if (a > b)
return a;
else
return b;
}
int go(bool stage)
{
int i, j, num, tmp, ans;
if (stage == RIGHT_TO_LEFT) {
num = 0;
ans = 0;
for (i = 1; i <= n; i++)
if (pos[i] == RIGHT) {
num++;
if (hour[i] > ans)
ans = hour[i];
}
if ( ① )
return ans;
ans = INFINITY;
for (i = 1; i <= n - 1; i++)
if (pos[i] == RIGHT)
for (j = i + 1; j <= n; j++)
if (pos[j] == RIGHT) {
pos[i] = LEFT;
pos[j] = LEFT;
tmp = max(hour[i], hour[j]) + ② ;
if (tmp < ans)
ans = tmp;
pos[i] = RIGHT;
pos[j] = RIGHT;
}
return ans;
}
if (stage == LEFT_TO_RIGHT) {
ans = INFINITY;
for (i = 1; i <= n; i++)
if ( ③ ) {
pos[i] = RIGHT;
tmp = ④ ;
if (tmp < ans)
ans = tmp;
⑤ ;
}
return ans;
}
return 0;
}
int main()
{
int i;
cin>>n;
for (i = 1; i <=n; i++) {
cin>>hour[i];
pos[i] = RIGHT;
}
cout<
return 0;
}
十六屆普及組初賽答案(C++)