3.24总结

 J - 哈密顿绕行世界问题

 

 分析:

  • 找出所有路,使用DFS
  • DFS的要点在于寻找终止条件,而这题最后要走到起点,如果以到再次找到起点作为终止条件,在DFS中实现不太方便,所以我们可以判断走到第20个点的时候,它的邻点有没有起点,如果有,说明该条路可以

 代码:

#include<iostream>
#include<vector>
using namespace std;
int m, book[21], a, b, c,ans[21],n;
vector<int>r[21];

void bfs(int v, int s)
{
	book[v] = 1;
	ans[s] = v;
	if (s == 19)
	{
		for (int i : r[ans[s]])
		{
			if (i == m)
			{
				cout << n++ << ": ";
				for (int j = 0; j < 20; j++)
					cout << ans[j] << ' ';
				cout << m << endl;
				
			}		
		}
		return;
	}
	for (int i : r[v])
	{
		if (!book[i])
		{
			bfs(i, s + 1);
			book[i] = 0;
		}
	}

}
int main()
{
	for (int i = 1; i <= 20; i++)
	{
		cin >> a >> b >> c;
		r[i].push_back(a);
		r[i].push_back(b);
		r[i].push_back(c);
	}
	while (cin >> m && m)
	{
		memset(book, 0, sizeof(book));
		n = 1;
		bfs(m, 0);
	}
	return 0;
}

 


 

O - 胜利大逃亡(续)

 

 分析:

  • 总共十把锁,所以每个点都有对应不同开锁情况的装态,在储存开锁情况是需要使用位运算;除了标记数组和普通BFS不一样,其他一样

代码:

#include<iostream>
#include<cstring>
using namespace std;
int n, m, t,book[21][21][1030];
char a[21][21];
int nx[] = { 0,1,0,-1 };
int ny[] = { 1,0,-1,0 };
struct nb
{
	int x;
	int y;
	int t;
	int f;
}r[4000];
int main()
{
	int x, y, c;
	while (scanf("%d%d%d", &n, &m, &t) != EOF)
	{
		memset(book, 0, sizeof(book));
           c = 0;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
			{
				scanf(" %c", &a[i][j]);
				if (a[i][j] == '@')
				{
					x = i;
					y = j;
				}
			}
		int head, tail, tx, ty;
		head = tail = 1;
		r[tail].x = x;
		r[tail].y = y;
		r[tail].t = 0;
		r[tail].f = 0;
		book[x][y][r[tail].f] = 1;
		tail++;
		while (head < tail)
		{
			for (int i = 0; i < 4; i++)
			{
				tx = r[head].x + nx[i];
				ty = r[head].y + ny[i];
				r[tail].t = r[head].t + 1;
				r[tail].f = r[head].f;
				r[tail].x = tx;
				r[tail].y = ty;
				if (tx < 0 || tx >= n || ty < 0 || ty >= m || book[tx][ty][r[head].f] == 1 || a[tx][ty] == '*' || r[tail].t >= t)
					continue;
				if (a[tx][ty] == '^')
				{
					c = 1;
					break;
				}

				else if (a[tx][ty] >= 'a' && a[tx][ty] <= 'j')
				{
					int s = a[tx][ty] - 'a';
					if ((r[tail].f & (1 << s)) == 0)
						r[tail].f += (1 << s);
				}
				else if (a[tx][ty] >= 'A' && a[tx][ty] <= 'J')
				{
					int s = a[tx][ty] - 'A';
					if ((r[tail].f & (1 << s)) == 0)
						continue;
				}
				book[tx][ty][r[tail].f] = 1;
				tail++;
			}
			head++;
			if (c == 1)
				break;
		}
		if (c == 1)
			printf("%d\n", r[tail].t);
		else
			printf("-1\n");
	}
	return 0;
}

 

 


 

P - Beat 

 

 分析:

  • 做的题的难度必须要大于等于做的前一题(难度也就是做题的时间)
  • 做完一道题后更新当前难度,重复搜索

代码:

#include<iostream>
using namespace std;
int n, a[20][20], vis[20], ans;
void DFS(int s, int q, int d)
{
	if (s > ans)
		ans = s;
	vis[q] = 1;
	for (int i = 0; i < n; i++)
	{
		if (!vis[i] && a[q][i] >= d)
			DFS(s + 1, i, a[q][i]);	
	}
	vis[q] = 0;
}
int main()
{
	while (cin>>n)
	{
		memset(vis, 0, sizeof(vis));
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				cin >> a[i][j];
		ans = 1;
		DFS(1, 0, 0);
		cout << ans<< endl;
	}
}

 

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值