【程序员面试宝典】找规律
都不是难题,但是我的脑子木木的,条件写的很混乱。
1.
数字如上,1对应坐标(0,0),向上y变小,向右x变大。给定坐标,输出值。
观察发现:
第n圈结束时,一共输出了(2n)2个数字。这样,我们判断当前在第几圈,并找到位置对应当前的第几个数字就可以得到结果。
int getNum(int x, int y) { int dx, dy, n, count; dx = (x <= 0) ? -x : x - 1; dy = (y <= 0) ? -y : y - 1; n = (dx > dy) ? dx : dy; //前面已经有完整的n圈 //第n圈(从1开始) //第一个数字的位置是 -(n-1), n-1 //第一个拐角的位置是 -(n-1), -(n-1) //第二个拐角的位置是 n, -(n-1) //第三个拐角的位置是 n, n int curn = n + 1; //当前的圈数 int d1 = 2 * (curn - 1) + 1; //第一个拐角前有几个数字(包括第一个拐角) int d2 = 2 * (curn - 1); //第一和第二个拐角间有几个数字(不包括两个拐角) int d3 = 2 * curn; //第二和第三个拐角中间有几个数字(包括两个拐角) if(n == dx) { if(x <= 0 && y <= curn - 1) //在第一个拐角前 { count = (curn - 1) - y + 1; } else if(x > 0) //在第三个拐角前 { count = y + (curn - 1) + 1 + d1 + d2; } else //最后一个数字 单独判断 { count = 2 * curn * 2 * curn - 2 * n * 2 * n; } } else { if(y <= 0) //在第二个拐角前 { count = x + (curn - 1) + d1; } else //在第三个拐角之后 { count = curn - x + d1 + d2 + d3; } } int num = 2 * n * 2 * n + count; return num; }
2.输入n, 输出n*n的之字形排列的数组,如下图:
思路:懒得找规律,直接按照数字的出现的情况来写代码。
数字的走向一共有4种情况:
向右:向下:向左下方:向右上方;
根据已有数字的大小和位置判断下一个数字应该出现在哪里。
void zigzag(int n) { int *a = new int[n * n]; memset(a, 0, n * n * sizeof(int)); int r = 0; int c = 0; for(int i = 0; i < n * n; i++) { a[r * n + c] = i; if((c < n - 1) && (((r == 0 || r == n - 1) && (c > 0 && a[r * n + c - 1] != i - 1)) || (c == 0 && (r == 0 || r == n - 1 && a[(r - 1) * n + c] != i - 1 )))) //向右走 { c = c + 1; } else if(((c == 0 || c == n - 1) && (r > 0 && a[(r - 1) * n + c] != i - 1)) || (r == 0 && c == n - 1 && a[r * n + c - 1] != i - 1)) //向下走 { r = r + 1; } else if(r == 0 || a[(r - 1) * n + c + 1] == i - 1 || c == n - 1 && a[(r - 1) * n + c] == i - 1) //向左下方走 { r = r + 1; c = c - 1; } else //向右上方走 { r = r - 1; c = c + 1; } } for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { printf("%4d ", a[i * n + j]); } printf("\n"); } delete [] a; }