阿里巴巴笔试题1.1

题目一: http://topic.csdn.net/t/20051128/09/4422199.html 请用最少的额外空间将一个M*N的矩阵旋转90度,写出算法描述和类c语言程序; Answer1: //功能:网上看到道题:用用最小空间度将一个M*N的矩阵旋转90度(顺逆时针均可) // 个人用五个额处空间(两个循环控制三个暂存)实现。 // 大家一起研究,再优化,如果算法有错欢迎指正 // 如果有更好的方法别忘了回贴 //作者:陈昂(http974@163.com) //算法说明: //设有一个(M×N)3*4维矩阵A,旋转后成4*3 // 1 2 3 4 9 5 1 // 5 6 7 8 => 10 6 2 // 9 10 11 12 11 7 3 // 12 8 4 //可以发现旋转后矩阵与原矩阵的关系: // 旋转后 原矩阵 // A[0,0] = A[2,0] = 9 // A[0,1] = A[1,0] = 5 // A[0,2] = A[0,0] = 1 // A[1,0] = A[2,1] = 10 // A[1,1] = A[1,1] = 6 // A[1,2] = A[0,1] = 2 // A[2,0] = A[2,2] = 11 // A[2,1] = A[1,2] = 7 // A[2,2] = A[0,2] = 3 // A[3,0] = A[2,3] = 12 // A[3,1] = A[1,3] = 8 // A[3,2] = A[0,3] = 4 //可以得出对应关系为:旋转后矩阵A[i,j] = 原矩阵A[ M- j -1, i ] //所以我们可以用同一个矩阵来保存转换前后的值 //用两层循环(注意外层为N,内层为M), //依次交换A[i,j] 与 A[ M- j -1, i ], //(交换不用额外存储空间,直接相加交换,如交换a和b的值:a= a+ b; b= a- b; a = a - b) //这样可以求出A[i,j]的值,原来A[i,j]的值则保存在A[ M- j -1, i ]中 //每一个A[i,j]都唯一对应一个A[ M- j -1, i ],所以我们从0开始依次求A[i,j]的值 //要注意的是如果A[ M- j- 1 ,i]在数组中存放的位置在A[i,j]之后,我们才做交换 //如果A[ M- j- 1 ,i]在A[i,j]之前,则说明A[ M- j- 1 ,i]已经交换过,其值存在对应的 //次A中,依次查找,直到找到位于A这后的对应元素即为该交换的值,下面用流程说明 // // ~A[x,y]表示A[i,j]对应在原矩阵中的元素. // 处理元素A[0,0](在数组中的位置为0), 其对应原矩阵的~A[2,0](对应位置为8),交换 // 处理元素A[0,1](位置为1),~A[1,0](位置为4),交换 // 处理元素A[0,2](位置为2),~A[0,0](位置为0),不交换, // 查找到位置为0的元素对应的~~A[2,0](位置为8),在其之后,即A[2,0]与A[0,0]交换过 // 直接交换A[0,2]和A[2,0] 转摘请注明:www.pghome.net // 依此类推。 // A[1,0](位置3) -> ~A[2,1](位置9) // A[1,1](位置4) -> ~A[1,1](位置6) // A[1,2](位置5) -> ~A[0,1](位置1)(交换过) -> ~~A[2,1] = A[1,0] // ... // A[3,2](位置11) -> ~A[0,3](位置2,对应新矩阵下标[1,0])(交换过) // -> ~~A[2,1](位置9) ...... ~~~~A[2,3] = 4 //为便于理解,可画出下面三个矩阵。 // 原矩阵 (存储方式相同的矩阵) 旋转后 // 1 2 3 4 1 2 3 9 5 1 // 5 6 7 8 => 4 5 6 => 10 6 2 // 9 10 11 12 7 8 9 11 7 3 // 10 11 12 12 8 4 #include #include const int M=3; const int N=4; main() { int Matrix[M][N]={1,2,3,4,5,6,7,8,9,10,11,12}; int i=0 ; int j=0 ; int tmpi = 0; int tmpj = 0; int u = 0; printf("原矩阵为:/n"); for (i= 0 ;i< M ;i++) { for(j=0 ; j< N; j++) printf(" %d ",Matrix[i][j]); printf("/n"); } printf("顺时针转90度后:/n"); for (i= 0 ;i< N ; i++) { for(j= 0 ; j< M; j++) { //求该交换元素在原矩阵对应的位置 tmpi = M- j -1; tmpj = i ; //循环查找最后交换的位置 while((tmpi * N + tmpj) < i * M + j ) { u= (tmpi * N + tmpj ); tmpi = u / M ; tmpj = u % M ; tmpi = tmpi + tmpj; tmpj = tmpi - tmpj; tmpi = tmpi - tmpj; tmpi = (M-tmpi -1); } //交换矩元素,后一个作暂存用 if (*(&Matrix[0][0] + i * M + j) != Matrix[tmpi][tmpj]) { *(&Matrix[0][0] + i * M + j) = *(&Matrix[0][0] + i * M + j) + Matrix[tmpi][tmpj]; Matrix[tmpi][tmpj] = *(&Matrix[0][0] + i * M + j) - Matrix[tmpi][tmpj]; *(&Matrix[0][0] + i * M + j) = *(&Matrix[0][0] + i * M + j) - Matrix[tmpi][tmpj]; } printf(" %d ",*(&Matrix[0][0] + i * M + j)); } printf("/n"); } getch(); return 0; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cyf31

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值