日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

2016年第七届蓝桥杯 - 国赛 - Java大学C组 - I. 路径之谜

發布時間:2024/5/6 java 73 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2016年第七届蓝桥杯 - 国赛 - Java大学C组 - I. 路径之谜 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

路徑之謎

小明冒充X星球的騎士,進入了一個奇怪的城堡。
城堡里邊什么都沒有,只有方形石頭鋪成的地面。

假設城堡地面是 n x n 個方格?!救鐖D1.png】所示。

按習俗,騎士要從西北角走到東南角。
可以橫向或縱向移動,但不能斜著走,也不能跳躍。
每走到一個新方格,就要向正北方和正西方各射一箭。
(城堡的西墻和北墻內各有 n 個靶子)

同一個方格只允許經過一次。但不必做完所有的方格。

如果只給出靶子上箭的數目,你能推斷出騎士的行走路線嗎?

有時是可以的,比如圖1.png中的例子。

本題的要求就是已知箭靶數字,求騎士的行走路徑(測試數據保證路徑唯一)

輸入:
第一行一個整數N(0<N<20),表示地面有 N x N 個方格
第二行N個整數,空格分開,表示北邊的箭靶上的數字(自西向東)
第三行N個整數,空格分開,表示西邊的箭靶上的數字(自北向南)

輸出:
一行若干個整數,表示騎士路徑。

為了方便表示,我們約定每個小格子用一個數字代表,從西北角開始編號: 0,1,2,3…
比如,圖1.png中的方塊編號為:

0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

示例:
用戶輸入:
4
2 4 3 4
4 3 3 3

程序應該輸出:
0 4 5 1 2 3 7 11 10 9 13 14 15

資源約定:
峰值內存消耗 < 256M
CPU消耗 < 1000ms

請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入…” 的多余內容。

所有代碼放在同一個源文件中,調試通過后,拷貝提交該源碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效代碼處理。

Ideas

這道題類似一個迷宮問題,迷宮問題想搜索,最優問題想廣搜,不然想深搜。

對于深搜函數DFS來說,肯定需要傳入一個位置坐標x和y,然后這道題還需要輸出騎士走的路徑,所以在最后找到一個符合條件的路徑之后還要輸出。

之后就是正常的DFS套路了,四個方向都走一走,保證不要越界,并且還需要一個visit數組表示某個位置是否被訪問過,最后從西北角搜索到東南角就OK了。

當然這道題還需要確保箭靶數字符合要求,所以我們其實可以利用這個條件做一個剪枝,當我們走到一個位置之后,其實可以把對應位置的兩個箭靶數字減去1,如果某一個位置箭靶數字剪成了負數,說明白不符合條件,就可以直接return。

Code

C++

#include <iostream> #include <vector>using namespace std;struct Node {bool flag;int x, y; };Node map[20][20]; vector<int> road; int N, X[20], Y[20], sum; int dir[4][2] = {{0, 1},{1, 0},{-1, 0},{0, -1}};bool dfs(int x, int y) {if (x == N - 1 && y == N - 1) {for (int i = 0; i < N; i++) {if (X[i] || Y[i] || sum)return false;road.push_back(x * N + y);return true;}}road.push_back(x * N + y);map[x][y].flag = true;for (int i = 0; i < 4; i++) {int tx = x + dir[i][0];int ty = y + dir[i][1];if (tx < 0 || tx > (N - 1) || ty < 0 || ty > (N - 1))continue;if (!map[tx][ty].flag && (X[tx] > 0 && Y[ty] > 0)) {X[tx]--;Y[ty]--;sum -= 2;if (dfs(tx, ty))return true;else {X[tx]++;Y[ty]++;sum += 2;}}}map[x][y].flag = false;road.erase(road.begin() + road.size() - 1);return false; }int main() {cin >> N;for (int i = 0; i < N; i++){cin >> Y[i];sum += Y[i];}for (int i = 0; i < N; i++) {cin >> X[i];sum += X[i];}for (int i = 0; i < N; i++) {for (int j = 0; j < N; j++) {map[i][j].flag = false;map[i][j].x = i;map[i][j].y = j;}}X[0]--;Y[0]--;sum -= 2;dfs(0, 0);for (int i = 0; i < road.size(); i++)cout << road[i] << ' ';return 0; }

Python

def dfs(r, c):"""Args:r: 當前搜索行c: 當前搜索列Returns: Bool值,表示是否找到了一條符合條件路徑"""if r == n - 1 and c == n - 1:if sum(north_target) > 0 or sum(west_target) > 0: # 如果最后還有箭靶上面的數目不為零,也不符合要求return Falsepath.append(r * n + c)print(' '.join(map(str, path)))return Truepath.append(r * n + c)direction = [(0, 1), (1, 0), (0, -1), (-1, 0)]for dr, dc in direction:nr, nc = r + dr, c + dc # 下一個搜索位置的行、列# 保證下一個搜索的位置符合要求if -1 < nr < n and -1 < nc < n and not visit[nr][nc] and north_target[nc] > 0 and west_target[nr] > 0:visit[nr][nc] = Truenorth_target[nc] -= 1west_target[nr] -= 1if dfs(nr, nc):return Trueelse:visit[nr][nc] = Falsenorth_target[nc] += 1west_target[nr] += 1path.pop()return Falseif __name__ == '__main__':n = int(input())north_target = list(map(int, input().split()))west_target = list(map(int, input().split()))path = []visit = [[False] * n for _ in range(n)]visit[0][0] = Truenorth_target[0] -= 1west_target[0] -= 1dfs(0, 0)

在線評測:https://www.acwing.com/problem/content/description/3193/


這道題至今只有1個人AC了,上面的代碼應該只能拿70分,求AC大佬分享。

總結

以上是生活随笔為你收集整理的2016年第七届蓝桥杯 - 国赛 - Java大学C组 - I. 路径之谜的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。