标签:
题意:
Y和M去KFC见面,有很多KFC,帮他们找一个KFC使得他们花费的时间总和最小
解题思路:
两次 bfs 分别找出他们到达他们都能到达的所有的KFC的最短时间
然后比较他们花费时间的和找出最小
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 200 + 5;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int dis[maxn][maxn][2];
int dir[][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int n, m;
struct Node {
int x, y;
int Count;
};
void bfs(int i, int j, int y_m);
int main()
{
// freopen("in.txt", "r", stdin);
while (cin>>n>>m) {
memset(dis, 0, sizeof(dis));
for (int i=0; i<n; ++i) {
for (int j=0; j<m; ++j) {
cin>>Map[i][j];
}
}
for (int i=0; i<n; ++i) {
for (int j=0; j<m; ++j) {
if (Map[i][j] == 'Y') {
memset(vis, false, sizeof(vis));
bfs(i, j, 0);
}
if (Map[i][j] == 'M') {
memset(vis, false, sizeof(vis));
bfs(i, j, 1);
}
}
}
int Min = INT_MAX;
for (int i=0; i<n; ++i) {
for (int j=0; j<m; ++j) {
if (Map[i][j] == '@') {
if (dis[i][j][0] > 0) {
int t = dis[i][j][0] + dis[i][j][1];
if (t < Min) {
Min = t;
}
}
}
}
}
cout<<Min*11<<endl;
}
return 0;
}
void bfs(int i, int j, int y_m)
{
Node node;
queue<Node> Queue;
node.x = i;
node.y = j;
node.Count = 0;
Queue.push(node);
vis[i][j] = true;
while (!Queue.empty()) {
int nx = Queue.front().x;
int ny = Queue.front().y;
int nCount = Queue.front().Count;
Queue.pop();
for (int i=0; i<4; ++i) {
node.x = nx + dir[i][0];
node.y = ny + dir[i][1];
node.Count = nCount + 1;
if ((node.x>=0) && (node.x<n) && (node.y>=0) && (node.y<m)) {
if (Map[node.x][node.y]!='#' && !vis[node.x][node.y]) {
Queue.push(node);
vis[node.x][node.y] = true;
dis[node.x][node.y][y_m] = node.Count;
}
}
}
}
}题意:
你的坦克每次每次可以进行两种操作,向四周的空地移动或者射击砖墙将它变成空地但是不移动
问到达目的地需要的最少操作次数
解题思路:
关键是要保证队列中的操作次数是递增的
一:
可以将射击砖墙不移动这个操作 改为 把砖墙当作“伪空地”然后移动到这个地方,以后若遇到“伪空地”则变成空地然后直接跳出循环
二、
优先队列
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 300 + 5;
int M, N;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int dir[][4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
struct Node {
int x, y;
int Count;
};
int bfs(int a, int b);
int main()
{
// freopen("in.txt", "r", stdin);
while (cin>>M>>N && !(M==0&&N==0)) {
memset(vis, false, sizeof(vis));
int x, y;
for (int i=0; i<M; ++i) {
for (int j=0; j<N; ++j) {
cin>>Map[i][j];
if (Map[i][j] == 'Y') {
x = i;
y = j;
}
}
}
int least = bfs(x, y);
cout<<least<<endl;
}
return 0;
}
int bfs(int a, int b)
{
queue<Node> Queue;
Node node;
node.x = a;
node.y = b;
node.Count = 0;
Queue.push(node);
vis[a][b] = 1;
while (!Queue.empty()) {
int nx = Queue.front().x;
int ny = Queue.front().y;
int nCount = Queue.front().Count;
Queue.pop();
if (Map[nx][ny] == 'T') {
return nCount;
}
if (Map[nx][ny] == 'B') {
Map[nx][ny] = 'E';
node.x = nx;
node.y = ny;
node.Count = nCount + 1;
Queue.push(node);
continue;
}
for (int i=0; i<4; ++i) {
node.x = nx + dir[i][0];
node.y = ny + dir[i][1];
if (node.x>=0 && node.x<M && node.y>=0 && node.y<N) {
if (!vis[node.x][node.y] && (Map[node.x][node.y] != 'R' && Map[node.x][node.y] != 'S')) {
node.Count = nCount + 1;
vis[node.x][node.y] = 1;
Queue.push(node);
}
}
}
}
return -1;
}#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 300 + 5;
int M, N;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int dir[][4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
struct Node {
int x, y;
int Count;
bool operator < (const Node &p) const{
return p.Count < Count;
}
};
int bfs(int a, int b);
int main()
{
// freopen("in.txt", "r", stdin);
while (cin>>M>>N && !(M==0&&N==0)) {
memset(vis, false, sizeof(vis));
int x, y;
for (int i=0; i<M; ++i) {
for (int j=0; j<N; ++j) {
cin>>Map[i][j];
if (Map[i][j] == 'Y') {
x = i;
y = j;
}
}
}
int least = bfs(x, y);
cout<<least<<endl;
}
return 0;
}
int bfs(int a, int b)
{
priority_queue<Node> Queue;
Node node;
node.x = a;
node.y = b;
node.Count = 0;
Queue.push(node);
vis[a][b] = 1;
while (!Queue.empty()) {
int nx = Queue.top().x;
int ny = Queue.top().y;
int nCount = Queue.top().Count;
Queue.pop();
if (Map[nx][ny] == 'T') {
return nCount;
}
for (int i=0; i<4; ++i) {
node.x = nx + dir[i][0];
node.y = ny + dir[i][1];
if (node.x>=0 && node.x<M && node.y>=0 && node.y<N) {
if (!vis[node.x][node.y] && (Map[node.x][node.y] != 'R' && Map[node.x][node.y] != 'S')) {
if (Map[node.x][node.y] == 'B') {
node.Count = nCount + 2;
} else {
node.Count = nCount + 1;
}
vis[node.x][node.y] = 1;
Queue.push(node);
}
}
}
}
return -1;
}#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 300 + 5;
int M, N;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int dir[][4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
struct Node {
int x, y;
int Count;
friend bool operator < (const Node &a, const Node &b) {
return b.Count < a.Count;
}
};
int bfs(int a, int b);
int main()
{
// freopen("in.txt", "r", stdin);
while (cin>>M>>N && !(M==0&&N==0)) {
memset(vis, false, sizeof(vis));
int x, y;
for (int i=0; i<M; ++i) {
for (int j=0; j<N; ++j) {
cin>>Map[i][j];
if (Map[i][j] == 'Y') {
x = i;
y = j;
}
}
}
int least = bfs(x, y);
cout<<least<<endl;
}
return 0;
}
int bfs(int a, int b)
{
priority_queue<Node> Queue;
Node node;
node.x = a;
node.y = b;
node.Count = 0;
Queue.push(node);
vis[a][b] = 1;
while (!Queue.empty()) {
int nx = Queue.top().x;
int ny = Queue.top().y;
int nCount = Queue.top().Count;
Queue.pop();
if (Map[nx][ny] == 'T') {
return nCount;
}
for (int i=0; i<4; ++i) {
node.x = nx + dir[i][0];
node.y = ny + dir[i][1];
if (node.x>=0 && node.x<M && node.y>=0 && node.y<N) {
if (!vis[node.x][node.y] && (Map[node.x][node.y] != 'R' && Map[node.x][node.y] != 'S')) {
if (Map[node.x][node.y] == 'B') {
node.Count = nCount + 2;
} else {
node.Count = nCount + 1;
}
vis[node.x][node.y] = 1;
Queue.push(node);
}
}
}
}
return -1;
}#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 300 + 5;
int M, N;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int dir[][4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
struct Node {
int x, y;
int Count;
};
bool operator < (const Node &a, const Node &b) {
return b.Count < a.Count;
}
int bfs(int a, int b);
int main()
{
// freopen("in.txt", "r", stdin);
while (cin>>M>>N && !(M==0&&N==0)) {
memset(vis, false, sizeof(vis));
int x, y;
for (int i=0; i<M; ++i) {
for (int j=0; j<N; ++j) {
cin>>Map[i][j];
if (Map[i][j] == 'Y') {
x = i;
y = j;
}
}
}
int least = bfs(x, y);
cout<<least<<endl;
}
return 0;
}
int bfs(int a, int b)
{
priority_queue<Node> Queue;
Node node;
node.x = a;
node.y = b;
node.Count = 0;
Queue.push(node);
vis[a][b] = 1;
while (!Queue.empty()) {
int nx = Queue.top().x;
int ny = Queue.top().y;
int nCount = Queue.top().Count;
Queue.pop();
if (Map[nx][ny] == 'T') {
return nCount;
}
for (int i=0; i<4; ++i) {
node.x = nx + dir[i][0];
node.y = ny + dir[i][1];
if (node.x>=0 && node.x<M && node.y>=0 && node.y<N) {
if (!vis[node.x][node.y] && (Map[node.x][node.y] != 'R' && Map[node.x][node.y] != 'S')) {
if (Map[node.x][node.y] == 'B') {
node.Count = nCount + 2;
} else {
node.Count = nCount + 1;
}
vis[node.x][node.y] = 1;
Queue.push(node);
}
}
}
}
return -1;
} 在中国象棋中,棋子活动的场所,叫做"棋盘",在长方形的平面上,绘有九条平行的竖线和十条平行横线相交组成,共九十个交叉点,棋子就摆在这些交叉点上。中间第五、第六两横线之间未画竖线的空白地带,称为"河界",整个棋盘就以"河界"分为相等的两部分;两方将帅坐镇、画有"米"字方格的地方,叫做"九宫"。
中国象棋中,马是威力很大的棋子。马走动的方法是一直一斜,即先横着或直着走一格,然后再斜着走一个对角线,俗称"马走斜"。马一次可走的选择点可以达到四周的八个点,故有"八面威风"之说。
我们约定最左下角点的坐标为(0,0),则最右上角的坐标为(9, 8)。上图中马在坐标(2, 2)处。它走一步可以到达坐标点(1, 0),(0, 1),(0, 3),(1, 4),(3, 4),(4, 3),(4, 1)或(3,0)。
我们约定当前棋盘上只有一个马,给出起点坐标和终点坐标,求从起点到终点,马最少要走几步?
Input
4个整数,前2个数表示起点坐标,后2个数表示终点坐标。
Output
一个整数,表示从起点到终点最少需要走的步数。
Sample Input
2 2 5 2
Sample Output
3
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
struct Node {
int x, y;
int steps;
};
const int maxn = 15;
bool vis[maxn][maxn];
int dir[][2] = {{-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}};
int x1, y1, x2, y2;
int bfs();
int main()
{
// freopen("in.txt", "r", stdin);
memset(vis, false, sizeof(vis));
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x1 = 9-x1;
x2 = 9-x2;
printf("%d\n", bfs());
return 0;
}
int bfs()
{
Node node;
node.x = x1;
node.y = y1;
node.steps = 0;
vis[x1][y1] = true;
queue<Node> Queue;
Queue.push(node);
while (!Queue.empty()) {
int nx = Queue.front().x;
int ny = Queue.front().y;
int ns = Queue.front().steps;
if (nx == x2 && ny == y2) {
return ns;
}
Queue.pop();
for (int i=0; i<8; ++i) {
node.x = nx + dir[i][0];
node.y = ny + dir[i][1];
node.steps = ns + 1;
if (0 <= node.x && node.x <= 9 && 0 <= node.y && node.y <= 8 && !vis[node.x][node.y]) {
vis[node.x][node.y] = true;
Queue.push(node);
}
}
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
struct Node {
int x, y;
int step;
};
const int maxn = 100 + 5;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int n, m;
int s_x, s_y, e_x, e_y;
int dir[][2] = {{-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}};
int flag[][2] = {{0, -1}, {-1, 0}, {-1, 0}, {0, 1}, {0, 1}, {1, 0}, {1, 0}, {0, -1}};
int bfs(void);
int main()
{
// freopen("in.txt", "r", stdin);
while (scanf("%d%d", &n, &m) != EOF) {
for (int i=0; i<n; ++i) {
for (int j=0; j<m; ++j) {
cin>>Map[i][j];
if (Map[i][j] == 's') {
s_x = i;
s_y = j;
} else if (Map[i][j] == 'e') {
e_x = i;
e_y = j;
}
}
}
printf("%d\n", bfs());
}
return 0;
}
int bfs(void)
{
memset(vis, false, sizeof(vis));
Node node;
node.x = s_x;
node.y = s_y;
node.step = 0;
vis[s_x][s_y] = true;
queue<Node> Queue;
Queue.push(node);
while (!Queue.empty()) {
int nx = Queue.front().x;
int ny = Queue.front().y;
int nstep = Queue.front().step;
if (nx == e_x && ny == e_y) {
return nstep;
}
Queue.pop();
for (int i=0; i<8; ++i) {
int a = nx + flag[i][0];
int b = ny + flag[i][1];
if (Map[a][b] == '.') {
node.x = nx + dir[i][0];
node.y = ny + dir[i][1];
node.step = nstep + 1;
if (node.x >= 0 && node.x <= n && node.y >=0 && node.y <= m && !vis[node.x][node.y] && Map[node.x][node.y] != '#') {
Queue.push(node);
vis[node.x][node.y] = true;
}
}
}
}
return -1;
}有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
答案:
116
解题思路:
一:
选出5张不同邮票
规律:
(1)
某个邮票的上下左右可以分别用 -4 , +4 ,-1, +1 来表示
但要注意特殊情况,比如4、8、5、9
(2)
每个邮票至少和其它的一个邮票相连
假如将邮票a与邮票b相连的边与邮票b与邮票a相连的边看成是不同的
那么相连的边数应该 ≥ 8
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 12 + 5;
int num[maxn];
bool vis[maxn];
bool live[5];
int Count = 0;
int dir[4] = {-4, 4, -1 , 1};
bool check(void);
int main()
{
for (int i=1; i<=8; ++i) {
vis[i] = true;
num[0] = i;
for (int j=i+1; j<=9; ++j) {
vis[j] = true;
num[1] = j;
for (int k=j+1; k<=10; ++k) {
vis[k] = true;
num[2] = k;
for (int x=k+1; x<=11; ++x) {
vis[x] = true;
num[3] = x;
for (int y=x+1; y<=12; ++y) {
vis[y] = true;
num[4] = y;
memset(live, false, sizeof(live));
if (check()) {
++Count;
}
vis[y] = false;
}
vis[x] = false;
}
vis[k] = false;
}
vis[j] = false;
}
vis[i] = false;
}
cout<<Count<<endl;
return 0;
}
bool check(void)
{
int edge = 0;
for (int i=0; i<4; ++i) {
for (int j=0; j<5; ++j) {
if (!((num[j] == 4 || num[j] == 8) && i == 3) && !((num[j] == 5 || num[j] == 9) && i == 2)) {
if (vis[num[j] + dir[i]] == 1) {
edge++;
live[j] = true;
}
}
}
}
if (edge >= 8 && live[0] && live[1] && live[2] && live[3] && live[4]) {
return true;
}
return false;
}
标签:
原文地址:http://blog.csdn.net/only_air/article/details/51292204