列表

详情


NC54663. 走迷宫

描述

Tyl 喜欢走迷宫,他走迷宫的策略如下:

  while(1){     if (前面没有障碍 && 前面还没有走过) 前进一步();      else if(右边没有障碍 && 右边还没有走过){       右转();       前进一步();     } else 原地愣住();   } 

现在他位于一个 n*m 的迷宫中(一共 n 行,每行 m 格)的第 1 行的第 1 格,幸运的是这个迷宫除了边缘的墙壁以外没有别的障碍。
他最初总是位于迷宫第一行的第一格,并且朝着右边,现在他想知道 k 秒后他的坐标(上述策略中循环 1 次就是 1 秒)。如果位于第 x 行第 y 格,坐标就是 (x,y) 。

以 3*3 的迷宫为例,Tyl 依次走过的区域如下:

  1 2 3   8 9 4   7 6 5

输入描述

第一行是一个整数 T(1<=T<=100),表示数据组数。
对于每一组数据:
第一行是两个整数 n,m (1<=n,m<=50000) ,表示迷宫的尺寸。
第二行是一个整数 q(1<=q<=100000) 表示询问个数。
接下来 q 行,每行一个整数 k(0<=k<=1000000000) ,表示一次询问。

输出描述

对于每一次询问,输出一行信息:k 秒后 Tyl 的坐标。

示例1

输入:

1
2 2
5
0
1
2
3
4 

输出:

(1,1)
(1,2)
(2,2)
(2,1)
(2,1) 

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 162ms, 内存消耗: 5652K, 提交时间: 2019-11-19 22:20:14

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;


int main()
{
	int t,q;
	long long k,m,n;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lld %lld",&n,&m);
		scanf("%d",&q);
		while(q--)
		{
			scanf("%lld",&k);
			k++;
			if(k>n*m)
				k=n*m;
			int M=min((n+1)/2,(m+1)/2);
			long long l=1,h=M;
			long long ans;
			while(l<=h)
			{
				long long mid=(l+h)/2;

				if(k>n*m-(n-2*(mid-1))*(m-2*(mid-1)))
				{
					ans=mid;
					l=mid+1;

				}
				else
				{
					h=mid-1;
				}
			}
			long long s=m-2*(ans-1);//lie
			long long e=n-2*(ans-1);//hang
			k-=n*m-s*e;
			if(k<=s)
				printf("(%lld,%lld)\n",ans,ans+k-1);
			else if(k>s && k<=s+e-1)
			{
				k-=s;
				printf("(%lld,%lld)\n",ans+k,ans+s-1);
			}
			else if(k>s+e-1 && k<=2*s+e-2)
			{
				k-=s+e-1;
				printf("(%lld,%lld)\n",ans+e-1,ans+s-k-1);
			}
			else
			{
				k-=2*s+e-2;
				printf("(%lld,%lld)\n",ans+e-1-k,ans);
			}
			
		}
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 135ms, 内存消耗: 5540K, 提交时间: 2019-11-18 17:39:58

#include<cstdio>
#include<cmath> 
#include<algorithm>
using namespace std;
typedef long long ll;
void solve(ll n,ll m,ll k){
	if(k>=n*m) k=n*m;
	ll d=((n+m)*2-ceil(sqrt((n+m)*(n+m)*4-k*16)))/8; 
	d=min(min(n/2,m/2),d);
	ll x=1+d,y=1+d;
	k-=(d*(n+m)*4-d*d*8)/2;
	n-=d*2,m-=d*2;
	if(!k) y--;
	else if(n==1) y+=k-1;
	else if(m==1) x+=k-1;
	else{
		if(k<=m) y+=k-1;
		else if(k<=n+m-1) y+=m-1,x+=k-m;
		else if(k<=n+m*2-2) x+=n-1,y+=m*2+n-k-2;
		else x+=(n+m)*2-k-3;
	}
	printf("(%d,%d)\n",x,y);
}
int main(){
	int t,q;
	ll n,m,k;
	scanf("%d",&t);
	while(t--){
		scanf("%lld%lld",&n,&m);
		scanf("%d",&q);
		while(q--){
			scanf("%lld",&k);
			solve(n,m,k+1); 
		}
	}
	return 0;
}

上一题