一道某互联网公司的笔试题(Android九宫格锁屏)
2014-11-24 01:40
302 查看
问题:android手机的锁屏屏幕,手指划过的距离最长为多少?
解法:
1、 这个题目首先可以判断要出现最长的滑动距离,必然是9个点都是用。
2、 约束条件:连接两个点之间的途径的那个点必须已经连接,这两个点才能连接。
3、 解决思想:
解决方法是通过递归方式遍历所有的9个点的连接方式,并计算每种连接方式的总长度,通过比较得到最长的长度值。
其中规定规定同一行两个相邻的点之间的距离为1。
代码实现如下(有详细注释解释):
最终得到的最长距离为:17.599998
解法:
1、 这个题目首先可以判断要出现最长的滑动距离,必然是9个点都是用。
2、 约束条件:连接两个点之间的途径的那个点必须已经连接,这两个点才能连接。
3、 解决思想:
解决方法是通过递归方式遍历所有的9个点的连接方式,并计算每种连接方式的总长度,通过比较得到最长的长度值。
其中规定规定同一行两个相邻的点之间的距离为1。
代码实现如下(有详细注释解释):
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<conio.h> //规定同一行两个相邻的点之间的距离为1。 const float LENGTH_A = 1.0f; const float LENGTH_B = 2.0f; const float LENGTH_C = 1.4f; const float LENGTH_D = 2.8f; const float LENGTH_E = 2.2f; //用于存放选出的点 int squared[3][3] = {0}; //int count = 0; int nCount = 0; float maxLength = 0.0; int xPrePos = -1; int yPrePos = -1; //判断此点是否已被占 int IsOccupied(int x, int y) { if (squared[x][y]) return 1; else return 0; } //判断两个点横向之间间隔的点是否已被占 int CheckIfMidllePosOfHorizontalIsOccupied(int x) { if (0 == IsOccupied(x, 1)) return 0; else return 1; } //判断两个点纵向之间间隔的点是否已被占 int CheckIfMidllePosOfVerticalIsOccupied(int y) { if (0 == IsOccupied(1, y)) return 0; else return 1; } //判断对角线中间的点是否被占 int CheckIfMidllePosOfDiagonalIsOccupied() { if (0 == IsOccupied(1, 1)) return 0; else return 1; } //判断一个点是否是四个顶点中的一个 int CheckIfPosIsCorner(int x, int y) { if ((0 == (x + y)) || (4 == (x + y)) || ((x != y) && (2 == (x + y)))) return 1; else return 0; } //查找前一个点的位置 void GetPrePos(int n) { int x, y; for(x = 0; x < 3; x++) { for(y = 0;y < 3; y++) { if(squared[x][y] == n-1) { xPrePos = x; yPrePos = y; return; } } } } //判断当前位置是否可以被占 int CheckIfPosCanBeOccupied(int x, int y, int n) { //如果这个位置没有被占用,进行放置的判断 if (0 == IsOccupied(x, y)) { //如果是第一个节点则直接放置,不用下面判断 if (1 == n) return 1; //结合这个节点之前已经放置的节点判断当前节点是否可以被连接占用 //通过判断这两个节点横坐标是否相同确定这两个点是否在同一行,进而判断 //这两点的纵坐标差的绝对值是否等于2来确定这两个点横向之间是否存在中间点 //当存在中间间隔点时,再调用CheckIfMidllePosOfHorizontalIsOccupied() //判断中间点是否被占。 else { xPrePos = -1; yPrePos = -1; GetPrePos(n); if (x == xPrePos && (2 == abs(y - yPrePos))) { if (CheckIfMidllePosOfHorizontalIsOccupied(x)) //中间节点已被占,此节点可占 return 1; else //中间节点未被占,此节点不可占 return 0; } //结合这个节点之前已经放置的节点判断当前节点是否可以被连接占用 //通过判断这两个节点是否是四个顶点中的两个,进而判断 //这两点是否正好处于对角线的两端来确定这两个点纵向之间是否存在中间点 //当存在中间间隔点时,再调用CheckIfMidllePosOfVerticalIsOccupied() //判断中间点是否被占。 else if (y == yPrePos && (2 == abs(x - xPrePos))) { if (CheckIfMidllePosOfVerticalIsOccupied(y)) //中间节点已被占,此节点可占 return 1; else //中间节点未被占,此节点不可占 return 0; } //结合这个节点之前已经放置的节点判断当前节点是否可以被连接占用 //通过判断这两个节点纵坐标是否相同确定这两个点是否在同一列,进而判断 //这两点的横坐标差的绝对值是否等于2来确定这两个点纵向之间是否存在中间点 //当存在中间间隔点时,再调用CheckIfMidllePosOfDiagonalIsOccupied() //判断中间点是否被占。 else if (CheckIfPosIsCorner(x, y) && CheckIfPosIsCorner(xPrePos, yPrePos) && ((x != xPrePos) && (y != yPrePos))) { if (CheckIfMidllePosOfDiagonalIsOccupied()) return 1; else return 0; } else return 1; } } else return 0; } //计算两点之间的长度 float LengthOfTwoNodes(int x, int y, int xPre, int yPre) { if ((abs(x - xPre) + abs(y - yPre)) == 1) return LENGTH_A; else if ((abs(x - xPre) + abs(y - yPre)) == 4) return LENGTH_D; else if ((abs(x - xPre) + abs(y - yPre)) == 3) return LENGTH_E; else if (((abs(x - xPre) + abs(y - yPre)) == 2) && (x != xPre && y != yPre)) return LENGTH_C; else return LENGTH_B; } //计算当前连接方式的总长度 float CalculateLength() { int x, y, xPre = -1, yPre = -1; float length = 0; for (int k = 1; k < 10; k++) { for(x = 0; x < 3; x++) { for(y = 0; y < 3; y++) { if(squared[x][y] == k) { //printf("qw = %d",squared[x][y]); //getchar(); if (k > 1) length+= LengthOfTwoNodes(x, y, xPre, yPre); //printf("length == %f",length); xPre = x; yPre = y; } } } } return length; } //递归遍历所有连接方式并计算总长度,得到最大长度。 void LongestPathOfAndroidScreenLock(int n) { int x, y; if (n == 10) { //CalculateLength(); if (CalculateLength() > maxLength) maxLength = CalculateLength(); //printf("len = %f",maxLength); //nCount++; return; } for (x = 0; x < 3; x++) { for (y = 0; y < 3; y++) { if (CheckIfPosCanBeOccupied(x, y, n)) { //xPrePos = x; //yPrePos = y; squared[x][y] = n; //count++; LongestPathOfAndroidScreenLock(n + 1); squared[x][y] = 0; } } } } int main() { LongestPathOfAndroidScreenLock(1); printf("\nThe longest distance for Android screen lock is : %f\n",maxLength); system("pause"); return 0; }
最终得到的最长距离为:17.599998
相关文章推荐
- 一道某高大上互联网公司的笔试题分享
- 一道某高大上互联网公司的笔试题分享
- 某知名IT公司最近的一道笔试编程题(C#)
- 一道游戏公司程序员笔试题
- 找工作笔试面试那些事儿(15)---互联网公司面试的零零种种和多家经验
- 找工作笔试面试那些事儿(15)---互联网公司面试的零零种种和多家经验
- 2011Android技术面试整理附有详细答案(包括百度、新浪、中科软等多家公司笔试面试题)
- 一道智力题(某公司笔试题)
- BAT及各大互联网公司2014前端笔试面试题--JavaScript篇
- 【游戏语音技术开发互联网公司】android 主程
- 某互联网公司2014年笔试题
- 2014年网易互联网在线笔试题一道
- BAT及各大互联网公司2014前端笔试面试题:HTML/CSS/JAVASCRIPT
- 各大互联网公司Android应用中TabHost的使用
- 【上市互联网公司】招聘android、ios、php、java、python
- 一道蛮好玩的题目——某顶尖游戏公司程序员笔试第一题(摔xbox)
- 【北京】猎头代知名互联网公司高薪急聘android、ios客户端开发工程师
- 2011Android技术面试整理附有详细答案(包括百度、新浪、中科软等多家公司笔试面试题)
- 互联网公司笔试常见陷阱
- BAT及各大互联网公司2014前端笔试面试题--JavaScript篇