您的位置:首页 > 其它

uva 10161 Ant on a Chessboard

2013-09-24 10:57 309 查看
对于这道题,我的思路是先列出矩阵的对角线元素的行列值对应的序号(行列值是一样的,这样一个一维数组就够存储了),然后用二分法去搜索序号为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);
}
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm uva