2016蓝桥杯C++A组路径之谜参考代码
之前在网上看到的多是Java 但是我没学过Java..... 找了一篇C的,调了很久很久很久.......
题目如下:
小明冒充X星球的骑士,进入了一个奇怪的城堡。
城堡里边什么都没有,只有方形石头铺成的地面。
假设城堡地面是 n x n 个方格。【如图1.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
假设城堡地面是 n x n 个方格。【如图1.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
代码如下:
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- int N;
- const int max = 20;
- int west[max];
- int north[max];
- int pic[max][max];
- int iv[400];
- int dicx[] = { 1,-1,0,0 };
- int dicy[] = { 0,0,1,-1 };
- int ans[400];
- int num;
- bool ok = false;
- bool isin(int x,int y)
- {
- if (x < N && x >= 0 && y < N && y >= 0)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- bool J()
- {
- for (int i = 0; i < N; i++)
- {
- if (north[i] != 0)
- return false;
- }
- for (int i = 0; i < N; i++)
- {
- if (west[i] != 0)
- return false;
- }
- return true;
- }
- bool isr(int x, int y)
- {
- if (west[y] >= 0 && north[x] >= 0)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- void dfs(int x,int y,int l)
- {
- if (pic[y][x] == N * N - 1 )//终止条件
- {
- if (J())
- {
- ans[l] = pic[y][x];
- ok = true;
- num = l;
- return;
- }
- else
- {
- return;
- }
- }
- if (isin(x, y) && !(bool)iv[pic[y][x]] && isr(x,y))//判断当前位置是否符合条件 1.在图内 2.未经过 3.可以经过
- {
- iv[pic[y][x]] = 1;//尝试
- ans[l] = pic[y][x];
- for (int i = 0; i < 4; i++)//判断当前位置能否继续求解
- {
- int y_tem = y + dicy[i];
- int x_tem = x + dicx[i];
- if (isin(x_tem, y_tem) && !(bool)iv[pic[y_tem][x_tem]] && north[x_tem] - 1 >=0 && west[y_tem] - 1 >= 0)
- {
- north[x_tem] = north[x_tem] - 1;//尝试
- west[y_tem] = west[y_tem] - 1;
- dfs(x_tem, y_tem, l + 1);
- if (ok) return;
- north[x_tem] = north[x_tem] + 1;//撤销
- west[y_tem] = west[y_tem] + 1;
- }
- }
- iv[pic[y][x]] = 0;//撤销
- return;
- }
- else
- return;
- }
- int main()
- {
- cin >> N;
- for (int i = 0; i < N; i++)
- {
- cin >> north[i];
- }
- for (int i = 0; i < N; i++)
- {
- cin >> west[i];
- }
- int k = 0;
- for (int i = 0; i < N; i++)
- {
- for (int n = 0; n < N; n++)
- {
- pic[i][n] = k;
- k++;
- }
- }
- for (int i = 0;i < 400; i++)
- {
- iv[i] = 0;
- }
- west[0]--;
- north[0]--;
- dfs(0, 0, 0);
- for (int i = 0; i<= num; i++)
- {
- cout << ans[i] << " ";
- }
- system("pause");
- return 0;
- }