一共15道不定項選擇+5道編程+2道問答
不定項選擇以及問答基本都是測試相關的內容,比較噁心的是選擇是不定項選擇,多選不得分,少選得一半分,下面主要說一下五道編程題:
1、小球下落問題
一個小球從初始高度爲H的地方下落,每次落地後反跳回原高度的一半; 再落下, 求它在第n次落地時,共經歷多少米?結果保留兩位小數:(n不超過五次)
輸入測試用例:1 5 2 (第一個數代表測試用例個數,第二個數代表小球下落的起始高度,最後一個數代表第n次落地)
輸出:10.00
這道題是全AC的
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int number;
cin>>number;
while (number--)
{
double height;
while (cin >> height){
double back = height;
double sum = 0.0;
int n;
cin >> n;
for (int i = 1; i <= n; i++){
sum += back + back / 2.0;
back /= 2.0;
}
cout << fixed << setprecision(2) << sum - back << endl;
}
}
return 0;
}
2、最小長方形問題
給定一系列2維平面點的座標(x, y),其中x和y均爲整數,要求用一個最小的長方形框將所有點框在內。長方形框的邊分別平行於x和y座標軸,點落在邊上也算是被框在內。
輸入測試用例: 測試輸入包含若干測試用例,每個測試用例由一系列座標組成,每對座標佔一行,其中|x|和|y|小於 231;一對0 座標標誌着一個測試用例的結束。注意(0, 0)不作爲任何一個測試用例裏面的點。一個沒有點的測試用例標誌着整個輸入的結束。
12 56
23 56
13 10
0 0
12 34
0 0
0 0
輸出:對每個測試用例,在1行內輸出2對整數,其間用一個空格隔開。第1對整數是長方形框左下角的座標,第2對整數是長方形框右上角的座標。
12 10 23 56
12 34 12 34
這道題是全AC的
#include <iostream>
using namespace std;
int main()
{
int x, y, max_x, min_x, max_y, min_y;
while (cin>>x>>y)
{
if (x == 0 && y == 0)
{
break;
}
max_x = min_x = x;
max_y = min_y = y;
while (cin>>x>>y)
{
if (x == 0 && y == 0)
{
break;
}
if (x > max_x)
{
max_x = x;
}
else if (x < min_x)
{
min_x = x;
}
if (y > max_y)
{
max_y = y;
}
else if (y < min_y)
{
min_y = y;
}
}
cout << min_x <<" "<< min_y <<" "<< max_x <<" "<< max_y << endl;
}
return 0;
}
3、N人圍圈報數問題
有n個人圍成一圈,按順序從1到n編號。從第一個人開始報數,報數3的人退出圈子,下一個人從1開始重新報數,報數3的人退出圈子。如此循環,直到留下最後一個人。依次輸出退出人的編號:
輸入測試用例:1 4 (第一個數代表測試用例個數,第二個數代表編號n)
輸出:3 2 4 1
這道題博主沒有全AC,通過了40%,提示算法複雜度過大,以下是博主40%的解法:
#include <iostream>
using namespace std;
int main()
{
int number;
cin >> number;
while (number--)
{
int i, j = 0, k = 0, n;
int a[50] = { 0 };
cin >>n;
for (i = 0; i < n; i++)
{
a[i] = 1;
}
for (i = 1; i < 4; i = i % 3 + 1)
{
if (3 == i && a[j] != 0)
{
a[j] = 0;
cout << j + 1 << " ";
k++;
if (n - 1 == k)
break;
j = (j + 1) % n;
continue;
}
if (0 == a[j])
{
j = (j + 1) % n;
i--;
continue;
}
j = (j + 1) % n;
}
for (i = 0; i < n; i++)
{
if (1 == a[i])
cout << i + 1 << endl;
}
}
return 0;
}
4、死亡騎士問題
不死族的巫妖王發工資拉,死亡騎士拿到一張N元的鈔票(記住,只有一張鈔票),爲了防止自己在戰鬥中頻繁的死掉,他決定給自己買一些道具,於是他來到了地精商店前.
死亡騎士:"我要買道具!"
地精商人:"我們這裏有三種道具,血瓶150塊一個,魔法藥200塊一個,無敵藥水350塊一個."
死亡騎士:"好的,給我一個血瓶."
說完他掏出那張N元的大鈔遞給地精商人.
地精商人:"我忘了提醒你了,我們這裏沒有找客人錢的習慣的,多的錢我們都當小費收了的,嘿嘿."
死亡騎士:"......"
死亡騎士想,與其把錢當小費送個他還不如自己多買一點道具,反正以後都要買的,早點買了放在家裏也好,但是要儘量少讓他賺小費.
現在死亡騎士希望你能幫他計算一下,最少他要給地精商人多少小費.
不死族的巫妖王發工資拉,死亡騎士拿到一張N元的鈔票(記住,只有一張鈔票),爲了防止自己在戰鬥中頻繁的死掉,他決定給自己買一些道具,於是他來到了地精商店前.
死亡騎士:"我要買道具!"
地精商人:"我們這裏有三種道具,血瓶150塊一個,魔法藥200塊一個,無敵藥水350塊一個."
死亡騎士:"好的,給我一個血瓶."
說完他掏出那張N元的大鈔遞給地精商人.
地精商人:"我忘了提醒你了,我們這裏沒有找客人錢的習慣的,多的錢我們都當小費收了的,嘿嘿."
死亡騎士:"......"
死亡騎士想,與其把錢當小費送個他還不如自己多買一點道具,反正以後都要買的,早點買了放在家裏也好,但是要儘量少讓他賺小費.
現在死亡騎士希望你能幫他計算一下,最少他要給地精商人多少小費.
輸入測試用例:
輸入數據的第一行是一個整數T(1<=T<=100),代表測試數據的數量.然後是T行測試數據,每個測試數據只包含一個正整數N(1<=N<=10000),N代表死亡騎士手中鈔票的面值.
注意:地精商店只有題中描述的三種道具.
2
900
250
輸出:對於每組測試數據,請你輸出死亡騎士最少要浪費多少錢給地精商人作爲小費.
0
50
這道題是全AC的
#include<iostream>
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
int N,sum=0;
cin>>N;
if(N<150)
sum=N;
if(N>=150&&N<200)
sum=N-150;
if(N>=200&&N<300)
sum=N-200;
if(N>=300)
sum=N%50;
cout<<sum<<endl;
}
return 0;
}
5、連連看問題
“連連看”相信很多人都玩過。沒玩過也沒關係,下面我給大家介紹一下遊戲規則:在一個棋盤中,放了很多的棋子。如果某兩個相同的棋子,可以通過一條線連起來(這條線不能經過其它棋子),而且線的轉折次數不超過兩次,那麼這兩個棋子就可以在棋盤上消去。不好意思,由於我以前沒有玩過連連看,諮詢了同學的意見,連線不能從外面繞過去的,但事實上這是錯的。現在已經釀成大禍,就只能將錯就錯了,連線不能從外圍繞過。玩家鼠標先後點擊兩塊棋子,試圖將他們消去,然後遊戲的後臺判斷這兩個方格能不能消去。現在你的任務就是寫這個後臺程序。
輸入測試用例:輸入數據有多組。每組數據的第一行有兩個正整數n,m(0<n<=1000,0<m<1000),分別表示棋盤的行數與列數。在接下來的n行中,每行有m個非負整數描述棋盤的方格分佈。0表示這個位置沒有棋子,正整數表示棋子的類型。接下來的一行是一個正整數q(0<q<50),表示下面有q次詢問。在接下來的q行裏,每行有四個正整數x1,y1,x2,y2,表示詢問第x1行y1列的棋子與第x2行y2列的棋子能不能消去。n=0,m=0時,輸入結束。注意:詢問之間無先後關係,都是針對當前狀態的!
3 4
1 2 3 4
0 0 0 0
4 3 2 1
4
1 1 3 4
1 1 2 4
1 1 3 3
2 1 2 4
3 4
0 1 4 3
0 2 4 1
0 0 0 0
2
1 1 2 4
1 3 2 3
0 0
輸出:每一組輸入數據對應一行輸出。如果能消去則輸出"YES",不能則輸出"NO"。
YES
NO
NO
NO
NO
YES
這道題博主沒做完,無法驗證是否能順利AC,這裏貼一段網上找到的相對靠譜的解法
#include <stdio.h>
#include <string.h>
int map[1005][1005], vis[1005][1005];
int dis[4][2] = { -1, 0, 0, 1, 1, 0, 0, -1 };
int n, m, f_x, f_y;
bool ispos;
// dfs開始
void dfs(int x, int y, int direct, int turn)
{
// 如果轉向大於2 或者 已經找到了 則直接返回
if (turn>2 || ispos == 1) return;
// 如果到了目標,直接判定可以連接,因爲之前轉向大於2的都返回了
if (x == f_x && y == f_y)
{
ispos = true;
return;
}
// 強大的剪枝啊=。=
if (turn == 2)
{
if (x != f_x && y != f_y) return;
else if (x == f_x)
if (direct != 1) return;
else if (y == f_y)
if (direct != 0) return;
}
int i, xx, yy;
// 四個方向的遍歷
for (i = 0; i<4; ++i)
{
xx = x + dis[i][0];
yy = y + dis[i][1];
// 邊界判定
if (xx<1 || yy<1 || xx>n || yy>m || vis[xx][yy] == 1) continue;
// 如果下一個點是0或者終點
if (map[xx][yy] == 0 || (xx == f_x && yy == f_y))
{
vis[xx][yy] = 1;
//根據原來的方向來確定是否轉向
if (direct == -1) dfs(xx, yy, i % 2, turn);
else if (direct == 0)
{
if (i % 2 == 1) dfs(xx, yy, 1, turn + 1);
else dfs(xx, yy, 0, turn);
}
else if (direct == 1)
{
if (i % 2 == 0) dfs(xx, yy, 0, turn + 1);
else dfs(xx, yy, 1, turn);
}
vis[xx][yy] = 0;
}
}
}
int main()
{
int i, j, q, s_x, s_y;
while (scanf("%d%d", &n, &m) != EOF)
{
if (n == 0 && m == 0) break;
// 輸入
for (i = 1; i <= n; ++i)
for (j = 1; j <= m; ++j)
scanf("%d", &map[i][j]);
scanf("%d", &q);
while (q--)
{
scanf("%d%d%d%d", &s_x, &s_y, &f_x, &f_y);
// 如果搜尋的兩個點不相等或者搜尋的點是空點(即搜尋的點有0)
if (map[s_x][s_y] != map[f_x][f_y] || map[s_x][s_y] == 0)
{
printf("NO\n");
continue;
}
// 如果搜尋兩個點都爲本身(去掉後增加了點時間)
if (s_x == f_x && s_y == f_y && map[s_x][s_y] != 0)
{
printf("NO\n");
continue;
}
// 初始化
memset(vis, 0, sizeof(vis));
ispos = false;
dfs(s_x, s_y, -1, 0);
// 判斷輸出
if (ispos) printf("YES\n");
else printf("NO\n");
}
}
return 0;
}