2、如图:
7 8 9 10
6 1 2 11
5 4 3 12
16 15 14 13
设“1”的坐标为(0,0) “7”的坐标为(-1,-1) 编写一个小程序,使程序做到输入坐标(X,Y)之后显示出相应的数字。
方法一、先求出需要拐弯的次数times以及最后一次拐弯后还需要走的步数dif。然后在主函数里计算最终的坐标位置。这种解法与题设不符合。不过写的挺好。
#include<iostream>
using namespace std;
enum X{RIGHT = 1, DOWN = 1, LEFT = -1, UP = -1};
void get_attribution(int in_num, int &dif, int ×)
{
int i = 0;
in_num--;
while(in_num >= 0)
{
in_num = in_num - (i/2+1);
times = i;
i++;
if(in_num >= 0)
dif = in_num;
}
}
void main()
{
int a = 7;
int dif = 0,times = 0;
get_attribution(a, dif, times);
int x = 0, y = 0;
for(int i = 1; i <= times; i++)
{
switch(i%4)
{
case 0:
y += UP * ((i-1)/2+1); break;
case 1:
x += RIGHT *((i-1)/2+1); break;
case 2:
y += DOWN*((i-1)/2+1); break;
case 3:
x += LEFT*((i-1)/2+1); break;
}
}
switch (times%4)
{
case 3:
y += UP * dif; break;
case 0:
x += RIGHT * dif; break;
case 1:
y += DOWN * dif; break;
case 2:
x += LEFT * dif; break;
}
cout<<x<<" "<<y<<endl;
}
方法二、求出内层正方形的大小,然后计算外围的偏移量,最终的结果即为两者相加。
#include <iostream>
#include <conio.h>
#include <math.h>
using namespace std;
int newVal(int x, int y)
{
//以结点1为原点
//以相邻两结点间的距离为单位(如结点2与结点3的之间线段)
//结点7所在的正方形(由结点2、3、4、5、6、7、8、9构成)的边长
//的一半为1,即结点7到原点1的最大投影距离为1。
//于是由结点坐标,可以求出此结点所在的正方形的投影距离:
int r = max(abs(x),abs(y));
//进行坐标变换,即把坐标原点移动到正方形的一个角结点上,
//使整个正方形落在第一象限,例如,当r=1时,将把坐标原点从结点1
//移动到结点7。
x += r;
y += r;
//正方形的边长,等于投影距离的两倍
int d = 2*r;
int s; //s为结点在自己的正方形的偏移量
if (y == 0)
s = 3*d + x;
else if (x == 0)
s = 2*d + (d-y);
else if (y == d)
s = d + (d-x);
else
s = y;
//pow((r+1),2)为内层的结点数。
//例如,结点10的内层由结点1和正方形A(2、3、4、5、7、8、10)构成
//这些内层的总结点数恰为:(正方形A的边长+1)的平方,
//因为:正方形A的边长 =(结点10所在正方形的半径-1)*2
//故:内层结点数 = (结点10所在正方形的边长-1)的平方
//结点值 = 在当前正方形的偏移量 + 内层的结点数
s += pow((d-1),2);
return s;
}
int main(int argc,char * argv[])
{
int x, y;
cout <<"请输入坐标(x y):";
while (cin>>x>>y)
{
cout <<"坐标所在的结点值为:"<<f(x, y)<<endl;
cout <<"请输入坐标(x y):";
}
return 0;
}