Newcoder 146 E.Touring cities(机智)

探讨在一个n×m网格中利用kk条传送路径寻找从起点出发覆盖所有节点并返回起点的最短路径问题。根据网格尺寸的奇偶性确定基本步骤数,并考虑通过特定传送路径减少步数的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

给出一个n×mn\times mn×m的网格,每个格子可以一步走向上下左右这四个相邻格子中的一个,给出kkk个传送路径,表示从一个点可以一步传送到另一个点,现在从(1,1)(1,1)(1,1)出发,要求用最少步数经过所有点一遍后回到(1,1)(1,1)(1,1)点,输出最少步数

Input

第一行一整数TTT表示用例组数,每组用例首先三个整数n,m,kn,m,kn,m,k,之后kkk行每行输入四个整数x1,y1,x2,y2x_1,y_1,x_2,y_2x1,y1,x2,y2表示(x1,y1),(x2,y2)(x_1,y_1),(x_2,y_2)(x1,y1),(x2,y2)两点之间有一个传送路径

(1≤T≤20,0≤k≤10,2≤n,m≤100,1≤n⋅m≤100)(1\le T\le 20,0\le k\le 10,2\le n,m\le 100,1\le n\cdot m\le 100)(1T20,0k10,2n,m100,1nm100)

Output

输出最少步数

Sample Input

3
2 2 1
1 1 2 2
3 3 1
1 1 3 3
3 3 0

Sample Output

4
9
10

Solution

n,mn,mn,m有一个为偶数时可以n⋅mn\cdot mnm步就遍历所有点回到(1,1)(1,1)(1,1)点,此时即为最少步数

n,mn,mn,m全部为奇数时,由于此时距(1,1)(1,1)(1,1)哈密顿距离为偶数的点的个数比距(1,1)(1,1)(1,1)哈密顿距离为奇数的点多两个,若以该点到(1,1)(1,1)(1,1)的哈密顿距离奇偶性将所有点分成奇点和偶点,那么每次只会从一个奇点到偶点,或者从一个偶点到奇点,故走到最后会剩下两个偶点,此时必然需要从一个偶点走到一个之前走过的奇点再走到最后一个偶点,此时步数最少为n⋅m+1n\cdot m+1nm+1,而多出的kkk条路径使得有可能让步数减一,即若某条路径是从偶点到达偶点的,那么有一步就可以不从偶点走到奇点,而是通过该条路径走向另一个偶点,使得最少步数为n×mn\times mn×m,故只要判断是否存在一条连接两个不同偶点的路径即可

Code

#include<cstdio>
using namespace std;
#define maxn 100
int T,n,m,k,a[maxn][4]; 
int check(int x,int y,int x1,int y1)
{
	if(x==x1&&y==y1)return 0;
	int s=x-1+y-1,t=x1-1+y1-1;
	if(s%2==0&&t%2==0)return 1;
	return 0;
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d%d",&n,&m,&k);
		for(int i=1;i<=k;i++)
			for(int j=0;j<4;j++)
				scanf("%d",&a[i][j]);
		if(n%2==0||m%2==0)printf("%d\n",n*m);
		else
		{
			int flag=0;
			for(int i=1;i<=k;i++)
				if(check(a[i][0],a[i][1],a[i][2],a[i][3]))
				{
					flag=1;
					break;
				}
			int ans=n*m+1-flag;
			printf("%d\n",ans);
		}
	}	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值