2024年3月18号题解

Dungeon Master

解题思路

  1. 给格子编号,从1开始,这样我们就可以构建一个图
  2. 对这个图跑迪杰斯特拉算法就可以得到我们需要的答案

代码实现

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf 
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 1000000

typedef struct {
	int from;
	int distance;
}ELEMENT;

typedef struct heap {
	ELEMENT* data;//´æ·ÅÔªËØµÄÊý×é 
	int size;//×îС¶ÑÖеÄÔªËØ¸öÊý 
	int maxSize;//¶ÑÖÐ×î¶àÄܹ»ÈÝÄɵÄÔªËØ¸öÊý 
}minHeap, * MinHeap;

MinHeap createMinHeap(int n);//´´½¨Ò»¸ö×î¶àÄܹ»ÈÝÄÉn¸öÔªËØµÄ×îС¶Ñ 
int MinHeapSize(MinHeap h);//·µ»Ø×îС¶ÑµÄÔªËØ¸öÊý 
bool isMinHeapFull(MinHeap h);//ÅжÏ×îС¶ÑÊDz»ÊÇÂúÁË 
bool addMinHeap(MinHeap h, ELEMENT item);//Íù×îС¶ÑÀïÃæÌí¼ÓÔªËØitem
ELEMENT deleteMinHeap(MinHeap h);//µ¯³ö×îС¶ÑµÄ¶Ñ¶¥ÔªËØ 
void MinHeapInsert(MinHeap h, int index);//ÔÚ×îС¶ÑindexλÖÃнøÀ´Ò»¸öÔªËØ£¬ËùÒÔÒªÏòÉϵ÷Õû£¬À´ÈöÑÈÔÈ»ÊÇÒ»¸ö×îС¶Ñ 
void MinHeapify(MinHeap h, int index);//ÔÚ×îС¶ÑindexλÖõÄÔªËØ±äСÁË£¬ËùÒÔÏòϵ÷Õû¶Ñ£¬À´ÈöÑÈÔÈ»ÊÇÒ»¸ö×îС¶Ñ 
bool isMinHeapEmpty(MinHeap h);//ÅжÏ×îС¶Ñ¿ÕÁËûÓÐ 
void swap(MinHeap h, int i, int j);//½»»»×îС¶ÑÖÐiºÍjλÖõÄÔªËØ 
int MinHeapCompare(ELEMENT a, ELEMENT b);//»ùÓÚijÖйæÔòÀ´±È½Ï,ÀàËÆÓë±È½ÏÆ÷ 
void freeMinHeap(MinHeap h);//ÊÍ·Å×îС¶ÑµÄ¿Õ¼ä 
ELEMENT peekMinHeap(MinHeap h);//µÃµ½×îС¶ÑÖеĶѶ¥ÔªËØ 

int head[N];
int w[2 * N];
int next[2 * N];
int to[2 * N];
int cnt = 1;
char s[31][31][31];
int dist[N];
bool v[N];
int l, r, c;
int start = 1;
int end = 1;
int num;
int to1;

void build();
void add(int s, int e, int v);

int main(int argc, char* argv[])
{
	while (sc("%d%d%d", &l, &r, &c), l != 0 || r != 0 || c != 0) {
		build();
		for (int i = 0; i < l; i++) {
			for (int j = 0; j < r; j++) {
				sc("%s", s[i][j]);
				for (int k = 0; k < c; k++) {
					if (s[i][j][k] == 'S') {
						start = i * r * c + j * c + k + 1;
					}
					else if (s[i][j][k] == 'E') {
						end = i * r * c + j * c + k + 1;
					}
				}
			}
		}

		for (int i = 0; i < l; i++) {
			for (int j = 0; j < r; j++) {
				for (int k = 0; k < c; k++) {
					if (s[i][j][k] != '#') {
						num = i * r * c + j * c + k + 1;

						if (j - 1 >= 0 && s[i][j - 1][k] != '#') {//bei
							to1 = num - c;
							add(num, to1, 1);
						}
						if (j + 1 < r && s[i][j + 1][k] != '#') {//nan
							to1 = num + c;
							add(num, to1, 1);
						}
						if (k + 1 < c && s[i][j][k + 1] != '#') {//dong
							to1 = num + 1;
							add(num, to1, 1);
						}
						if (k - 1 >= 0 && s[i][j][k - 1] != '#') {//xi
							to1 = num - 1;
							add(num, to1, 1);
						}
						if (i - 1 >= 0 && s[i - 1][j][k] != '#') {//shang
							to1 = num - (r * c);
							add(num, to1, 1);
						}
						if (i + 1 < l && s[i + 1][j][k] != '#') {
							to1 = num + (r * c);
							add(num, to1, 1);
						}
					}
				}
			}
		}

		/*for (int i = 1; i <= l * r * c; i++) {
			pr("%d:\n", i);
			for (int j = head[i]; j; j = next[j]) {
				pr("%d\t", to[j]);
			}
			pr("\n");
		}*/

		MinHeap h = createMinHeap(cnt);

		dist[start] = 0;

		ELEMENT t = { start, 0 };

		addMinHeap(h, t);

		while (!isMinHeapEmpty(h)) {
			t = deleteMinHeap(h);

			if (!v[t.from]) {
				for (int i = head[t.from]; i; i = next[i]) {
					to1 = to[i];

					if (!v[to1] && t.distance + w[i] < dist[to1]) {
						dist[to1] = t.distance + w[i];
						ELEMENT temp = { to1, dist[to1] };
						addMinHeap(h, temp);
					}
				}
			}
			v[t.from] = 1;
		}

		if (dist[end] != INT_MAX) {
			pr("Escaped in %d minute(s).\n", dist[end]);
		}
		else {
			pr("Trapped!\n");
		}

		freeMinHeap(h);
	}

	return 0;
}

void add(int s, int e, int v)
{
	next[cnt] = head[s];
	w[cnt] = v;
	to[cnt] = e;
	head[s] = cnt++;
}

void build()
{
	cnt = 1;
	for (int i = 0; i <= l * r * c; i++) {
		head[i] = 0;
		dist[i] = INT_MAX;
		v[i] = 0;
	}
}

MinHeap createMinHeap(int n)
{
	MinHeap h = (MinHeap)malloc(sizeof(minHeap));//¿ª±ÙÒ»¸ö×îС¶Ñ 

	h->data = (ELEMENT*)malloc(sizeof(ELEMENT) * n);//¿ª±ÙÒ»¸ön¸ö¿Õ¼äµÄELEMENTÊý×é 
	h->size = 0;//³õʼ»¯×îС¶ÑÔªËØÊÇ0 
	h->maxSize = n;//×îС¶ÑÄÜ´æ·Å×î´óÔªËØµÄ¸öÊýÊÇn 

	return h;//·µ»Ø×îС¶Ñ 
}
int MinHeapSize(MinHeap h)
{
	return h->size;//·µ»Ø×îС¶ÑÖеÄÔªËØ¸öÊý 
}
bool isMinHeapFull(MinHeap h)
{
	return h->size == h->maxSize;//Èç¹û×îС¶ÑÖеÄÔªËØ¸öÊýµÈÓÚÄܹ»ÈÝÄɵÄ×î´óÔªËØ¸öÊý£¬ÄÇôÂúÁË 
}
bool addMinHeap(MinHeap h, ELEMENT item)
{
	if (isMinHeapFull(h)) {//Èç¹û×îС¶ÑÒѾ­ÂúÁË£¬ÄÇô¾Í²»ÄÜÌí¼ÓÔªËØÁË£¬·µ»Øfalse 
		return false;
	}

	h->data[h->size] = item;//°Ñitem·ÅÔÚ×î϶ÑÖÐÔªËØ¸öÊýµÄϱêÖÐ,ÒòÎªÔªËØ¸öÊýµÄϱê¾ÍÊÇÒª·ÅµÄλÖà 
	MinHeapInsert(h, h->size);//ÒòΪ¸Õ¸ÕнøÀ´Ò»¸öÔªËØ£¬ËùÒÔÏëÈöѼÌÐø±£³Ö×îС¶Ñ£¬ÄÇô¾ÍÐèÒªÏòÉϵ÷Õû¶Ñ 
	h->size++;//ÈÃ×îС¶ÑÖеÄÔªËØ¸öÊý¼ÓÒ» 

	return true;//Ìí¼Ó³É¹¦·µ»Øtrue 
}
ELEMENT deleteMinHeap(MinHeap h)
{
	if (isMinHeapEmpty(h)) {//Èç¹û×îС¶ÑÖÐûÓÐÔªËØ£¬ÄÇô²»ÄܽøÐÐɾ³ý£¬Î¥·¨·µ»ØÒ»¸öÌØ¶¨µÄÖµ£¬¼´ERROR 
		ELEMENT t = { 0 };

		return t;
	}

	ELEMENT ans = h->data[0];//·µ»Ø×îС¶ÑÖеĶѶ¥ÔªËØ 
	swap(h, 0, --h->size);//°Ñ×îС¶ÑÖеÄ×îºóÒ»¸öÔªËØÓë¶Ñ¶¥ÔªËؽøÐн»»»£¬²¢ÇÒÈöÑÖÐÔªËØ¼õÒ»£¬ÄÇô¾Í·ÃÎʲ»µ½¸Õ¸Õ±»É¾³ýµÄÔªËØÁË¡£ 
	MinHeapify(h, 0);//ϱê0λÖõÄÔªËØ±ä´óÁË£¬ÄÇôΪÁ˼ÌÐø±£³ÖÒ»¸ö×îС¶Ñ£¬¾ÍÒªÏòϵ÷Õû 

	return ans;//·µ»Ø×îС¶ÑÖеĶѶ¥ÔªËØ 
}
void MinHeapInsert(MinHeap h, int index)//indexλÖõÄÊýÏòÉϵ÷ÕûС¸ù¶Ñ 
{
	while (MinHeapCompare(h->data[index], h->data[(index - 1) / 2]))//Èç¹ûϱêindexµÄֵСÓÚËüµÄ¸¸½Úµã 
	{
		swap(h, index, (index - 1) / 2);//ϱêindexµÄÖµºÍËüµÄ¸¸½ÚµãµÄÖµ½»»» 
		index = (index - 1) / 2;//¸üÐÂindexµÄλÖà 
	}
}
bool isMinHeapEmpty(MinHeap h)
{
	return !h->size;//Èç¹û×îС¶ÑÖеÄÔªËØÊÇ0¸ö£¬ÄÇô¾ÍÊǿգ¬ÓÐÔªËØ¾Í²»ÊÇ¿Õ 
}
void swap(MinHeap h, int i, int j)
{
	ELEMENT t = h->data[i];
	h->data[i] = h->data[j];
	h->data[j] = t;
}
void MinHeapify(MinHeap h, int index)
{
	int left = 2 * index + 1;//¼ÆËãϱêindexµÄ×óº¢×Ó 

	while (left < h->size) {//Èç¹ûÓк¢×Ó 
		int lessest = left + 1 < h->size && MinHeapCompare(h->data[left + 1], h->data[left]) ? left + 1 : left;//Èç¹ûÓÐÓÒº¢×Ó²¢ÇÒÓÒº¢×ÓСÓÚ×óº¢×Ó£¬ÄÇôº¢×ÓÖÐ×îСµÄ¾ÍÊÇÓÒº¢×Ó£¬·ñÔò¾ÍÊÇ×óº¢×Ó 

		lessest = MinHeapCompare(h->data[index], h->data[lessest]) ? index : lessest;//Èç¹û¸¸Ç×½Úµã±Èº¢×ÓÖÐ×îСµÄ»¹ÒªÐ¡£¬ÄÇô×îСµÄ½Úµã¾ÍÊǸ¸½Úµã£¬²»È»×îСµÄ½Úµã¾ÍÊǺ¢×ÓÖÐ×îСµÄ½Úµã 

		if (lessest == index) {//Èç¹û×îСµÄ½ÚµãÊǸ¸½Úµã£¬ÄÇô²»ÓüÌÐøÁË£¬ÒѾ­ÊÇ×îС¶ÑÁË 
			break;
		}

		swap(h, index, lessest);//Óë×îСµÄº¢×Ó½øÐн»»» 
		index = lessest;//¸üÐÂindexϱ꣬ÒòΪ¸Õ¸Õ½»»»ÁË 
		left = 2 * index + 1;//ÖØÐ¼ÆËãϱêindexµÄ×óº¢×Ó 
	}
}
int MinHeapCompare(ELEMENT a, ELEMENT b)
{
	return a.distance < b.distance;//Ö±½Ó½øÐÐÖµµÄ±È½Ï 
}
void freeMinHeap(MinHeap h)
{
	free(h->data);//ÏÈÊÍ·Å×îС¶Ñ´æ·ÅÔªËØµÄ¿Õ¼ä 
	free(h);//ÔÙÊÍ·Å×îС¶ÑµÄ¿Õ¼ä 
}
ELEMENT peekMinHeap(MinHeap h)
{
	if (isMinHeapEmpty(h)) {//×îС¶ÑÀïÃæÃ»ÓÐÔªËØÄÇô£¬²Ù×÷Î¥·¨£¬·µ»ØÌض¨Öµ 
		ELEMENT t = { 0 };

		return t;
	}

	ELEMENT ans = deleteMinHeap(h);//µ¯³ö×îС¶ÑµÄ¶Ñ¶¥ 

	addMinHeap(h, ans);//ÔÙ·ÅÈë×îС¶Ñ£¬ÒÔ´ËÀ´ÊµÏÖ´úÂ븴Óà 

	return ans;
}

Find The Multiple

解题思路

  1. 暴力所有倍数的话会很慢
  2. 因为答案是只包含0101的数字,所以我们可以直接生成一个只有0101的数字,再判断是不是n的倍数

代码实现

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf 
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 101

int n;
bool isans = 0;

void dfs(ll m, int bit);

int main(int argc, char* argv[])
{
	while (sc("%d", &n), n) {
		dfs(1, 1);
		isans = 0;
	}

	return 0;
}

void dfs(ll m, int bit)
{
	if (bit == 20) {
		return;
	}

	if (isans) {
		return;
	}

	if (m % n == 0) {
		pr("%lld\n", m);
		isans = 1;
		return;
	}

	dfs(10 * m, bit + 1);
	dfs(10 * m + 1, bit + 1);
}

Oil Deposits

解题思路

  1. 扫描整个矩阵利用洪水填充,进行感染在一个油田的油

代码实现

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf 
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 101

char s[N][N];
int n;
int m;
int cnt;
int d[8][2] = {
	{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}
};

void dfs(int i, int j)
{
	if (s[i][j] == '#') {
		return;
	}

	s[i][j] = '#';

	for (int k = 0; k < 8; k++) {
		int nx = i + d[k][0];
		int ny = j + d[k][1];

		if (nx >= 0 && nx < n && ny >= 0 && ny < m && s[nx][ny] == '@') {
			dfs(nx, ny);
		}
	}
}

int main(int argc, char* argv[])
{
	while (sc("%d%d", &n, &m), n + m) {
		cnt = 0;
		for (int i = 0; i < n; i++) {
			sc("%s", s[i]);
		}

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (s[i][j] == '@') {
					dfs(i, j);
					cnt++;
				}
			}
		}
		pr("%d\n", cnt);
	}



	return 0;
}

Find a way

解题思路

  1. 求两遍最短路径数组,一个从M出发,另一个从Y出发
  2. 遍历所有肯德基的最短路径,并求出其中最短的。

代码实现

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf 
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 201

typedef struct {
	int x;
	int y;
	int step;
}p;

int d[4][2] = {
	{-1, 0}, {1, 0} , {0, -1}, {0, 1}
};
int n;
int m;
char s[N][N];
int sSize;
int eSize;
int ans;
int y[N][N];
int ms[N][N];
p start[2];
p end[N * N];
p q[N * N];
int l = 0;
int r = 0;

void bfs(p start, int a[][N]);
int min1(int a, int b);

int main(int argc, char* argv[])
{
	while (~sc("%d%d", &n, &m)) {
		ans = INT_MAX;
		l = 0;
		r = 0;
		sSize = 0;
		eSize = 0;
		for (int i = 0; i < n; i++) {
			sc("%s", s[i]);

			for (int j = 0; j < m; j++) {
				if (s[i][j] == 'Y' || s[i][j] == 'M') {
					start[sSize].step = 0;
					start[sSize].x = i;
					start[sSize++].y = j;
				}
				else if (s[i][j] == '@') {
					end[eSize].x = i;
					end[eSize].y = j;
					end[eSize++].step = 0;
				}
			}
		}

		bfs(start[0], y);
		l = 0;
		r = 0;
		bfs(start[1], ms);

		for (int i = 0; i < eSize; i++) {
			if (y[end[i].x][end[i].y] != 0 && ms[end[i].x][end[i].y] != 0) {
				ans = min1(ans, y[end[i].x][end[i].y] + ms[end[i].x][end[i].y]);
			}
		}

		pr("%d\n", ans * 11);
	}

	return 0;
}

int min1(int a, int b) {
	return a <= b ? a : b;
}

void bfs(p start, int a[][N]) {
	p t = { 0 };
	p temp = { 0 };
	bool v[N][N] = { 0 };

	v[start.x][start.y] = 1;

	q[r++] = start;

	while (l < r) {
		t = q[l++];

		for (int i = 0; i < 4; i++) {
			int nx = t.x + d[i][0];
			int ny = t.y + d[i][1];

			if (nx >= 0 && nx < n && ny >= 0 && ny < m && s[nx][ny] != '#' && !v[nx][ny]) {
				a[nx][ny] = t.step + 1;

				temp.x = nx;
				temp.y = ny;
				temp.step = t.step + 1;
				q[r++] = temp;
				v[nx][ny] = 1;
			}
		}
	}
}

 

posted @ 2024-03-19 22:47  lwj1239  阅读(25)  评论(0)    收藏  举报