uva 10161 Ant on a Chessboard

对于这道题,我的思路是先列出矩阵的对角线元素的行列值对应的序号(行列值是一样的,这样一个一维数组就够存储了),然后用二分法去搜索序号为n的点夹在哪两个对角线节点之间,然后再在这两个对角线节点之间寻找正确的坐标点,注意行列值为1的时候和行列值为其他的奇数和偶数的时候,总共要分成三种情况来处理,因为对角线节点的行列值不一样的话,点的下一步移动方向不同。下面是AC代码。

节点移动的示意图如下:

 

#include <stdio.h>
#include <map>
#include <algorithm>
using namespace std;

unsigned int arr[50005]; //arr[i]代表节点 (i,i)的序号为arr[i]

void func(unsigned int n)
{
	//先用二分法寻找n号节点夹在那两个对角线节点之间
	unsigned int l, r, m;
	int row, col;

	l = 1;
	r = 50000;
	while(1)
	{
		m = (l+r)/2;

		if(n>=arr[m] && n<arr[m+1])
			break;
		else if(n >= arr[m+1])
			l = m+1;
		else
			r = m-1;
	}

	if(1 == m)
	{
		if(1 == n)
		{
			row = 1;
			col = 1;
		}
		else
		{
			row = 1;
			col = 2;
		}
		goto end;
	}

	if(m%2 == 0)
	{
		if(n-arr[m] <= m-1)
		{
			row = m;
			col = m-(n-arr[m]);
		}
		else
		{
			row = m+1;
			col = (n-arr[m])-m+1;
		}
		goto end;
	}
	else
	{
		if(n-arr[m] <= m-1)
		{
			row = m-(n-arr[m]);
			col = m;
		}
		else
		{
			row = (n-arr[m])-m+1;
			col = m+1;
		}
		goto end;
	}

end:
	printf("%d %d\n", row, col);
}

//初始化对角线上的节点的序号
void init()
{
	int i;
	int add;

	arr[1] = 1;
	add = 2;
	for(i=2; i<=50000; i++)
	{
		arr[i] =arr[i-1]+add;
		add += 2;
	}
}

int main(void)
{
	unsigned int N;
	init();

	while(scanf("%u", &N))
	{
		if(0 == N)
			break;

		func(N);
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值