您的位置:首页 > 其它

Betsy's Tour

2013-12-13 20:39 176 查看
题意:摘自NOCOW翻译(http://www.nocow.cn/index.php/Translate:USACO/betsy


翻译

一个正方形的镇区分为 N*N 个小方块(1 <= N <= 7)。农场位于方格的左上角,集市位于左下角。贝茜穿过小镇,从左上角走到左下角,刚好经过每个方格一次。当 N=3 时,贝茜的漫游路径可能如下图所示:
----------------
|    |    |    |
| F**********  |
|    |    | *  |
------------*---
|    |    | *  |
|  *****  | *  |
|  * | *  | *  |
---*---*----*---
|  * | *  | *  |
|  M | ******  |
|    |    |    |
----------------


写一个程序,对于给出的 N 值,计算贝茜从农场走到集市有多少种唯一的路径。


[编辑]格式

PROGRAM NAME: betsy

INPUT FORMAT

行 1: 一个整数 N (1 <= N <= 7)

OUTPUT FORMAT 只有一行。输出一个整数表示唯一路径的数量。


[编辑]SAMPLE
INPUT (file betsy.in)

3


[编辑]SAMPLE
OUTPUT (file betsy.out)

2


解题思路:

参考NOCOW“优化一”和“优化二”
自己的优化,在走到右边界或者下边界的时候,已走的路径将把正方形分为左右或者上下两个部分。如果右边或者上边有未访问的节点,这些点是访问不到的,直接剪枝
代码

/*
ID: zc.rene1
LANG: C
PROG: betsy
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX_N 7

int N;
int visited[MAX_N + 1][MAX_N + 1];
int free_space[MAX_N + 1][MAX_N + 1];
int total_num;

void GetInput(FILE *fin)
{
int i, j;

fscanf(fin, "%d", &N);
memset(visited, 0, (MAX_N + 1) * (MAX_N + 1) * sizeof(int));
total_num = 0;

for (i=1; i<=N; i++)
{
for (j=1; j<=N; j++)
{
if (i == 1 || i == N || j == 1 || j == N)
{
free_space[i][j] = 3;
}
else
{
free_space[i][j] = 4;
}
}
}
free_space[1][1] = 2;
free_space[1]
= 2;
free_space
[1] = 2;
free_space

= 2;
}

int AllVisited(void)
{
int i, j, count = 0;

for (i=1; i<=N; i++)
{
for (j=1; j<=N; j++)
{
if (visited[i][j] == 1)
{
count++;
}
}
}

if (count == N * N)
{
return 1;
}
else
{
return 0;
}
}

int UDSeparate(void)
{
int up_count = 0;
int i, j;

for (j=1; j<=N; j++)
{
i = 1;
while (visited[i++][j] == 0)
{
up_count++;
}
}

if (up_count != 0)
{
return 1;
}
else
{
return 0;
}
}

int LRSeparate(void)
{
int right_count = 0;
int i, j;

for (i=1; i<=N; i++)
{
j = N;
while (visited[i][j--] == 0)
{
right_count++;
}
}

if (right_count != 0)
{
return 1;
}
else
{
return 0;
}
}

void SetFree(int i, int j, int k)
{
if (i > 1)
{
free_space[i - 1][j] += k;
}
if (i < N)
{
free_space[i + 1][j] += k;
}
if (j > 1)
{
free_space[i][j - 1] += k;
}
if (j < N)
{
free_space[i][j + 1] += k;
}
}

int FreeAround(int i, int j)
{
int count = 0;

if (i == N && j == 1)
{
return 0;
}

if (i > 1 && visited[i - 1][j] == 0)
{
count++;
}
if (i < N && visited[i + 1][j] == 0)
{
count++;
}
if (j > 1 && visited[i][j - 1] == 0)
{
count++;
}
if (j < N && visited[i][j + 1] == 0)
{
count++;
}

return count;
}

int CountFree(int i, int j, int *m, int *n)
{
int count = 0;

if (i > 1 && visited[i - 1][j] == 0 && free_space[i - 1][j] == 1)
{
if (i - 1 != N || j != 1)
{
*m = -1;
*n = 0;
count++;
}
}
if (i < N && visited[i + 1][j] == 0 && free_space[i + 1][j] == 1)
{
if (i + 1 != N || j != 1)
{
*m = 1;
*n = 0;
count++;
}
}
if (j > 1 && visited[i][j - 1] == 0 && free_space[i][j - 1] == 1)
{
if (i != N || j - 1 != 1)
{
*m = 0;
*n = -1;
count++;
}
}
if (j < N && visited[i][j + 1] == 0 && free_space[i][j + 1] == 1)
{
if (i != N || j + 1 != 1)
{
*m = 0;
*n = 1;
count++;
}
}
return count;
}

int DFS(int i, int j)
{
int k, m, n;

visited[i][j] = 1;
SetFree(i, j, -1);

if (i == N && j == 1)
{
if (AllVisited())
{
total_num++;
visited[i][j] = 0;
SetFree(i, j, 1);
return ;
}
else
{
visited[i][j] = 0;
SetFree(i, j, 1);
return ;
}
}

if (i > 1 && i < N && j > 1 && j < N)
{
if (visited[i + 1][j] + visited[i - 1][j] == 2)
{
if (visited[i][j + 1] + visited[i][j - 1] == 0)
{
visited[i][j] = 0;
SetFree(i, j, 1);
return ;
}
}
if (visited[i][j + 1] + visited[i][j - 1] == 2)
{
if (visited[i + 1][j] + visited[i - 1][j] == 0)
{
visited[i][j] = 0;
SetFree(i, j, 1);
return ;

4000
}
}
}

if (j == N)
{
if (UDSeparate())
{
visited[i][j] = 0;
SetFree(i, j, 1);
return ;
}
}
if (i == N)
{
if (LRSeparate())
{
visited[i][j] = 0;
SetFree(i, j, 1);
return ;
}
}

k = CountFree(i, j, &m, &n);

if (k >= 2)
{
visited[i][j] = 0;
SetFree(i, j, 1);
return ;
}
else if (k == 1)
{
DFS(i + m, j + n);
}
else
{
if (i > 1 && visited[i - 1][j] == 0)
{
DFS(i - 1, j);
}
if (i < N && visited[i + 1][j] == 0)
{
DFS(i + 1, j);
}
if (j > 1 && visited[i][j - 1] == 0)
{
DFS(i, j - 1);
}
if (j < N && visited[i][j + 1] == 0)
{
DFS(i, j + 1);
}
}

visited[i][j] = 0;
SetFree(i, j, 1);
}

int main(void)
{
FILE *fin, *fout;

fin = fopen("betsy.in", "r");
fout = fopen("betsy.out", "w");

GetInput(fin);
DFS(1, 1);
fprintf(fout, "%d\n", total_num);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: