BUAA OJ 858 群鸦的盛宴
题目描述
AlvinZH总是比别人慢一拍,比如暑假大家都在追权游7讨论龙母和雪诺大人尴尬相遇的时候,他还在第一季震惊地看着三只刚出生的小龙。AlvinZH的进度很慢,因为他一边刷着电视剧,一边还在看原版小说,所以现在才看到第五季,雪诺在这头,龙母在那头。
AlvinZH发现书中各城堡之间的通信工具都是乌鸦,经过训练的乌鸦能够及时传递消息,使得主角总能绝处逢生。简化一下问题,假设维斯特洛大陆各领地分布如下图,信鸦只能从左向右飞行传信(1只能到2或3),AlvinZH想知道信鸦在两个领地间传信时的可能路线数,他想到了你们,快帮帮他。
输入
第一个数为数据组数n。
接下来n行,每行2个整数a,b(0<a<b≤50)。
输出
对于每组数据,输出一行,为信鸦从领地a飞到领地b的可能路线数。
输入样例
2
1 2
2 6
输出样例
1
5
解题思路
bfs 广度优先搜索
竟然没看出是斐波那契……
bfs竟然过了……
实际上这题可以先算出斐波那契数列,根据起点和终点的关系算出是数列的第几项。
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cstring>
#define NOT_VISITED 0
#define IN_QUEUE 1
#define VISITED 2
using namespace std;
typedef long long ll;
ll land[2][30];
int direc2[3][2] = {
{-1, 1},
{0, 1},
{1, 0}
};
int direc1[3][2] = {
{1, 0},
{0, 1},
{-1, 1}
};
int visited[2][30];
ll bfs(int a, int b) {
memset(land, 0, sizeof(land));
memset(visited, 0, sizeof(visited));
queue<int> que;
que.push(a);
int now;
int aX = a % 2 == 1 ? 0 : 1;
int aY = a / 2 - aX;
land[aX][aY] = 1;
int bX = b % 2 == 1 ? 0 : 1;
int bY = b / 2 - bX;
while (!que.empty()) {
now = que.front();
que.pop();
int x = now % 2 == 1 ? 0 : 1;
int y = now / 2 - x;
visited[x][y] = VISITED;
int nextX, nextY;
for (int i = 0; i < 3; ++i) {
if (aX == 0) {
nextX = x + direc1[i][0];
nextY = y + direc1[i][1];
} else {
nextX = x + direc2[i][0];
nextY = y + direc2[i][1];
}
if (nextY > bY)
continue;
if (nextX < 2 && nextX >= 0 && nextY < 25) {
land[nextX][nextY] += land[x][y];
if (visited[nextX][nextY] == NOT_VISITED) {
que.push((nextY + 1) * 2 - (nextX == 0 ? 1 : 0));
visited[nextX][nextY] = IN_QUEUE;
}
}
}
}
return land[bX][bY];
}
int main() {
int n, a, b;
scanf("%d", &n);
while (n--) {
scanf("%d%d", &a, &b);
printf("%lld\n", bfs(a, b));
// for (int i = 0; i < 2; ++i) {
// for (int j = 0; j < 25; ++j) {
// printf("%d ", land[i][j]);
// }
// putchar('\n');
// }
}
}