1. 程式人生 > >2016阿里校招演算法崗筆試題——魔方

2016阿里校招演算法崗筆試題——魔方

筆試被虐慘,選擇題一半多的概率題,每道題差不多3、5分鐘,so,最後好幾個沒有算。

附加兩個大題,一個是編寫魔方,另一個是機器學習的分佈不均衡問題和SVM。魔方題沒有寫完,機器學習的題目也只答了一問...

當天晚上把魔方的程式碼完善了下,沒有找到好的解法,硬寫的,麻煩的要死。

晚上的時候網上已經有題目了,詳情如下,最後結果的輸出其實不一定要與題目一致,因為每一面的方向沒有明確定義,顏色對了即可,比如本文的程式裡,Y面與題目的Y面相差180度:

 一個三階魔方由六個面組成,顏色分別是白色(W)、對面為黃色(Y)、紅色(R)、對面為橙色(O)、綠色(G)、對面為藍色(B)。如果手持魔方,白色向上,紅色朝向自己,則綠色在左手側。
請寫一個程式,對一個處於還原狀態(各面各塊同色)的魔方,進行操作,列印操作後的魔方狀態。操作指令為單個操作指令組成的字串。單個操作指令包括:
1)U:白色面順時針旋轉90度
2)D:黃色面順時針旋轉90度
3)F:紅色面順時針旋轉90度
4)B:橙色面順時針旋轉90度
5)L:綠色面順時針旋轉90度
6)R:藍色面順時針旋轉90度
其中順時針旋轉定義為將該面朝向自己時的順時針方向。
按WYROGB的順序輸出經過操作後6個面的狀態。每個面首先輸出中心塊顏色,然後從此面面向自己時的左下角塊開始,順時針順出每塊的顏色。輸出一面後換行。
請設計一個數據結構表示魔方,並基於該資料結構完成功能。
請用C/C++,Java或Python語言實現。請注意儘量以可成功編譯或可直接執行為標準來編寫程式碼。
 
示例:
輸入:
LR
輸出:
WOOOWRRRW
YRRRYOOOY
RWWWRYYYR
OYYYOWWWO
GGGGGGGGG
BBBBBBBBB

程式碼如下:

#include <stdio.h>
#include <stdlib.h>

struct panel {
    //暴力解法,每個面的面板顏色和四個接觸的邊
    int a[3][3];    //每個面的顏色
    char status;    //本面的顏色符號
    struct panel *u;    //四個相鄰的面
    int ul;     //相鄰的邊是相應面的那一條1-6表示1-3行+1-3列,-號表示逆序
    struct panel *r;
    int rl;
    struct panel *d;
    int dl;
    struct panel *l;
    int ll;
    };

typedef struct panel PP;

void initPanel(PP *p, int color);
void changePanel(PP *p, PP *u, PP *r, PP *d, PP *l);
void rot(PP *p);
void getLine(PP *p,int line,int b[]);
void setLine(PP *p,int line ,int b[]);
int abValue(int x);
void printPanel(PP *p, int check);
char intTochar(int i);
void printA(int a[]);

int main(int argc, char **argv)
{
    char c;
    
	PP Wp;
    PP Op;
    PP Bp;
    PP Rp;
    PP Gp;
    PP Yp;
    
    //定義每個面的顏色
    initPanel(&Wp,1);
    initPanel(&Op,2);
    initPanel(&Bp,3);
    initPanel(&Rp,4);
    initPanel(&Gp,5);
    initPanel(&Yp,6);
    
    /*給白色面定義四個臨邊,尼瑪太麻煩了,有好一點的演算法沒?
    以這個方向定義,輸出也是用的這個方向
    
         ---
        | O |
     --- --- --- ---
    | G | W | B | Y |
     --- --- --- ---
        | R |
         ---
    */
    Wp.status = 'W';
    Wp.u = &Op;
    Wp.ul = 3;
    Wp.r = &Bp;
    Wp.rl = 4;
    Wp.d = &Rp;
    Wp.dl = 1;
    Wp.l = &Gp;
    Wp.ll = 6;
    //橘色定義
    Op.status = 'O';
    Op.u = &Yp;
    Op.ul = -1;
    Op.r = &Bp;
    Op.rl = -1;
    Op.d = &Wp;
    Op.dl = 1;
    Op.l = &Gp;
    Op.ll = 1;
    //藍色定義
    Bp.status = 'B';
    Bp.u = &Op;
    Bp.ul = -6;
    Bp.r = &Yp;
    Bp.rl = 4;
    Bp.d = &Rp;
    Bp.dl = 6;
    Bp.l = &Wp;
    Bp.ll = 6;
    //紅色定義
    Rp.status = 'R';
    Rp.u = &Wp;
    Rp.ul = 3;
    Rp.r = &Bp;
    Rp.rl = 3;
    Rp.d =&Yp;
    Rp.dl = -3;
    Rp.l = &Gp;
    Rp.ll = -3;
    //綠色定義
    Gp.status = 'G';
    Gp.u = &Op;
    Gp.ul = 4;
    Gp.r = &Wp;
    Gp.rl = 4;
    Gp.d = &Rp;
    Gp.dl = -4;
    Gp.l = &Yp;
    Gp.ll = 6;
    //黃色定義
    Yp.status = 'Y';
    Yp.u = &Op;
    Yp.ul = -1;
    Yp.r = &Gp;
    Yp.rl = 4;
    Yp.d = &Rp;
    Yp.dl = -3;
    Yp.l = &Bp;
    Yp.ll = 6;
    
    while((c = getchar()) != '\n'){
        if(c == 'U')
            changePanel(&Wp, Wp.u, Wp.r, Wp.d, Wp.l);   //改變本面和相鄰的四個面
        if(c == 'D')
            changePanel(&Yp, Yp.u, Yp.r, Yp.d, Yp.l);
        if(c == 'F')
            changePanel(&Rp, Rp.u, Rp.r, Rp.d, Rp.l);
        if(c == 'B')
            changePanel(&Op, Op.u, Op.r, Op.d, Op.l);
        if(c == 'L')
            changePanel(&Gp, Gp.u, Gp.r, Gp.d, Gp.l);
        if(c == 'R')
            changePanel(&Bp, Bp.u, Bp.r, Bp.d, Bp.l);
    }
    
    //輸出每一個面,注意輸出的順序,1代表與定義順序一致,0代表翻轉180
    printPanel(&Wp, 1);
    printPanel(&Yp, 0);
    printPanel(&Rp, 1);
    printPanel(&Op, 1);
    printPanel(&Gp, 1);
    printPanel(&Bp, 1);
    
	return 0;
}

//初始每個面的顏色
void initPanel(PP *p, int color){
    int i,j;
    
    for(i = 0;i < 3;i++)
        for(j = 0;j < 3;j++)
        p->a[i][j] = color;
    
        
    }

//旋轉
void changePanel(PP *p, PP *u, PP *r, PP *d, PP *l){
    
    //旋轉本面二維陣列
    rot(p);
    
    //旋轉四個邊
    int ua[3],ra[3],da[3],la[3];
    int i,j;
    getLine(p->u,p->ul,ua);
    getLine(p->r,p->rl,ra);
    getLine(p->d,p->dl,da);
    getLine(p->l,p->ll,la);
    
    //輸出本面的當前四個邊
    printf("%c %dth is\n",p->u->status,p->ul);
    printA(ua);
    printf("%c %dth is\n",p->r->status,p->rl);
    printA(ra);
    printf("%c %dth is\n",p->d->status,p->dl);
    printA(da);
    printf("%c %dth is\n",p->l->status,p->ll);
    printA(la);
    printf("\n");
    
    //轉換4條邊,由於下邊和左邊的定義順序是左到右、上到下排列,與順時針方向相反,在轉換時要注意
    for(i = 0;i < 3;i++){
        j = ua[i];
        ua[i] = la[2-i];
        la[2-i] = da[2-i];
        da[2-i] = ra[i];
        ra[i] = j;
        }
    
    //輸出旋轉後本面的當前四個邊
    printf("%c %d th is\n",p->u->status,p->ul);
    printA(ua);
    printf("%c %d th is\n",p->r->status,p->rl);
    printA(ra);
    printf("%c %d th is\n",p->d->status,p->dl);
    printA(da);
    printf("%c %d th is\n",p->l->status,p->ll);
    printA(la);
    printf("\n");
    
    //將旋轉後的4個邊賦值給相應的臨面 
    setLine(p->u,p->ul,ua);
    setLine(p->r,p->rl,ra);
    setLine(p->d,p->dl,da);
    setLine(p->l,p->ll,la);
    
    }

//旋轉二維陣列,注意每一行交換兩個
void rot(PP *p){
    int i,j;
    for(i = 0; i < 2; i++){
        j = p->a[0][i];
        p->a[0][i] = p->a[2-i][0];
        p->a[2-i][0] = p->a[2][2-i];
        p->a[2][2-i] = p->a[i][2];
        p->a[i][2] = j;
        }
    }

//獲取面的某條邊資料
void getLine(PP *p,int line,int b[]){
    int i;
    
    if(abValue(line) < 4){
        for(i = 0;i < 3;i++){
            if(line < 0)
                b[i] = p->a[abValue(line) - 1][2-i];
            if(line > 0)
                b[i] = p->a[line - 1][i];
            }
        }
    else if(abValue(line) >= 4){
        for(i = 0;i < 3;i++){
            if(line < 0)
                b[i] = p->a[2-i][abValue(line) - 4];
            if(line > 0)
                b[i] = p->a[i][line - 4];
            }
        }
    }

//賦值面的某條邊
void setLine(PP *p,int line ,int b[]){
    int i;
    
    if(abValue(line) < 4){
        for(i = 0;i < 3;i++){
            if(line < 0)
                p->a[abValue(line) - 1][2-i] = b[i];
            if(line > 0)
                p->a[line - 1][i] = b[i];
            }
        }
    else if(abValue(line) >= 4){
        for(i = 0;i < 3;i++){
            if(line < 0)
                p->a[2-i][abValue(line) - 4] = b[i];
            if(line > 0)
                p->a[i][line - 4] = b[i];
            }
        }
    }

//取絕對值
int abValue(int x){
    if(x < 0)
        return 0-x;
    else
        return x;
    }

//check為定義如何輸出,定義每一面時是按照正方體展開的方向,最下面的Y貌似與定義順序不同
void printPanel(PP *p, int check){
    int i,j,k;
    if(check == 1){
        //正序,j+k*正序下標,無變化
        j = 0;
        k = 1;
    }
    else if(check == 0){
        //逆序下標=2-正序下標 j+k*正序下標
        j = 2;
        k = -1;
        }
//輸出二維陣列,先輸出中心點,再輸出4個邊,左下開始順時針
printf("%c",intTochar(p->a[1][1]));
for(i = 0;i < 2;i++)
    printf("%c",intTochar(p->a[j+k*(2-i)][j+k*0]));
for(i = 0;i < 2;i++)
    printf("%c",intTochar(p->a[j+k*0][j+k*i]));
for(i = 0;i < 2;i++)
    printf("%c",intTochar(p->a[j+k*i][j+k*2]));
for(i = 0;i < 2;i++)
    printf("%c",intTochar(p->a[j+k*2][j+k*(2-i)]));
printf("\n");
    }

//由數字顏色轉為字元
char intTochar(int i){
    
    switch(i){
        case 1:
          return 'W';
          break;
        case 2:
          return 'O';
          break;
        case 3:
          return 'B';
          break;
        case 4:
          return 'R';
          break;
        case 5:
          return 'G';
          break;
        case 6:
          return 'Y';
          break;
        default:
          return 'N';
          break;
        }
        
    }

//輸出暫存陣列
void printA(int a[]){
    printf("%c",intTochar(a[0]));
    printf("%c",intTochar(a[1]));
    printf("%c",intTochar(a[2]));
    printf("\n");
    }


相關推薦

2016阿里演算法試題——魔方

筆試被虐慘,選擇題一半多的概率題,每道題差不多3、5分鐘,so,最後好幾個沒有算。 附加兩個大題,一個是編寫魔方,另一個是機器學習的分佈不均衡問題和SVM。魔方題沒有寫完,機器學習的題目也只答了一問... 當天晚上把魔方的程式碼完善了下,沒有找到好的解法,硬寫的,麻煩的要死

阿里演算法測試題——n個節點的完全圖,每兩個節點之間路經m條線的最短距離

光明小學的小朋友們要舉行一年一度的接力跑大賽了,但是小朋友們卻遇到了一個難題:設計接力跑大賽的線路,你能幫助他們完成這項工作麼? 光明小學可以抽象成一張有N個節點的圖,每兩點間都有一條道路相連。光明小學的每個班都有M個學生,所以你要為他們設計出一條恰好經過M條邊的路徑。 光明

滴滴2017演算法工程師試題--吃飯問題

import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; public class Main { p

2016阿里安全工程師實習生招聘試題

一共十道問答題 2. 1)請描述一下fuzz的主要思想和優缺點 2)近幾年,很多Linux核心提權漏洞都和核心驅動的ioctl函式相關;請設計一套fuzz方案,對其進行漏洞挖掘。 3.給你的APP做一個手勢密碼的功能,忽略UI部分的實現,請從安全的角度出發,描述你的實現

演算法經驗總結(看了大概15篇左右面經)

    聽說17年頭條演算法崗白菜價30W+,加上之前實驗室師兄說現在開發崗扎堆比較嚴重,建議我們研一的,離找工作還有一段時間的學弟學妹關注一下演算法崗。。。於是,一口氣刷了十幾篇演算法崗的面經。。。。 下面總結一下他們是如何準備的,還有留一些比較經典的非科班出身的演算法手的

2017騰訊暑期實習生試題1

構造迴文給定一個字串s,你可以從中刪除一些字元,使得剩下的串是一個迴文串。如何刪除才能使得迴文串最長呢? 輸出需要刪除的字元個數。輸入描述:輸入資料有多組,每組包含一個字串s,且保證:1<=s.length<=1000. 輸出描述:對於每組資料,輸出一個整數,

巨人網路2015-產品專員試題

一、選擇題 1.        6(9)3  11(12)7  15(27)16  20(21)13  25()17 2.        甲乙同時做一項工作,內容相同,效率不同。開始時約定給甲2100元,給乙1400元。在專案的第5天,甲的工作效率提升了100%,結果最後少

2019網易內推試題--俄羅斯方塊得分

題目描述: 自定義俄羅斯方塊列數,每次俄羅斯方塊下落個數為1*1,當一行都落滿俄羅斯方塊時,得分+1。現在小明玩到m個俄羅斯方塊,求此時的分數。 輸入: 第一行: 列數, 俄羅斯方塊個數m 第二行 :a(1) a(2) a(3) …a(i)…a(m) 表

百度2018春 演算法工程師試題--程式設計題2--爬山

這次百度演算法工程師筆試題中的兩個程式設計題目,第一個是排列組合問題,很鬧心,耗費了不少時間,搞得第二道也沒做完,平時還是要多練習呀。題目: 爬山內容:冬木市西邊的園藏山是著名的旅遊勝地。從空中俯瞰,園藏山可以看成一個n*m的矩陣,我們把行從上往下按1到n編號,把列從左到右按

每日一題之 騰訊演算法試題 (字串Hash)

####描述 給定A,B兩個字串,定義如下規則 對於每一個A的長度為k的不同子串,統計子串在B中出現的次數 A和B的字串係數就是所有出現次數之和。 如 A=“abab“ B = “ababab“ k

2017網易內推試題

本人筆試的計算機視覺方向,程式設計題和其他研發崗位類似。 歡迎小夥伴們一起討論出正確答案。 共20個選擇題,3個程式設計題,1個簡答題 一.選擇題 1.Linux中,提供TCP/IP包過濾功能的軟體叫什麼? A.iptables B.r

2017吉位元一個程式設計試題

題目: 給定一個未排序的數列,找到此數列在已排序狀態下的兩個相鄰值的最大差值,少於兩個值時返回0。例如:給定數列[1,3,2,0,1,6,8]則最大差值為3。 輸入描述: 第一行輸入單個整數N作為數列的大小,第二行輸入所有數列中的元素M,共N個。N在0到1

拼多多試題(前端工程師)

0) 考試時間:2017-09-02-提前批內推-筆試 為了筆試結束後總結,我考試時截了圖,然後選取幾道有質量的題目。總的來說,坑還是很多的。 測試程式碼:所在倉庫 1) 測試程式碼如下: var a = {}; b = { key: 'b' }

15、2016騰訊研發試題(第二題)用Java實現

有下圖的題解,請用 C/C++ 程式碼來列出滿足下圖 0-100 內的所有答案。 分析: a1+a2-9=4 (1) a4-a5*a6=4 (2) a7+a8-a9=4 (3) a1+a4/a7=4 (4)

Keep2019屆演算法試題

1. 輸入一個字串和整數k,每3k個子串,將子串前面的k個字元反轉,後面2*k個子串保持原樣。如果剩餘的子串長度不足3k,則如果長度小於k,此末尾子串全部反轉,如果剩餘的子串長度大於k且小於3k,則把前面的k個子串翻轉,後面的末尾字元都保持原樣。 程式碼如下: #incl

2016小米試題

1 給定一些線段,線段有起點和終點,求這些線段的覆蓋長度,重複的部分只計算一次。 方法一: 首先說排序對於處理很多問題都是非常有效的,例如尋找兄弟單詞等問題中,經過排序處理後,問題就明朗了很多; 線段覆蓋長度也是這樣,將線段排序後,然後掃描一遍就可以得到覆蓋的長度。

2017-08-25阿里試題---菜鳥倉庫

”’ 阿里巴巴校招筆試附加題2菜鳥倉庫貨架編號問題 題目複述: 倉庫編號為0-9整數 以下為一示例: 1| 12| 123| 1234| 12345| ……|1234567891011

2014微軟秋季演算法試題

這道題是來自2014微軟秋季校招筆試題的最後一道演算法筆試題,本部落格提供程式碼解析及程式碼實現!!! 第二部分測試時間為60分鐘,滿分50分。請務必在回答問題前仔細閱讀變成題目。您可以選用C、C++、C#或者Java 其中任何一種程式語言,並且保證您的程式碼可以正確編譯和

2016微軟試題

標題 A string s is LUCKY if and only if the number of different characters in s is a fibonacci number. Given a string consisting of

騰訊2016實習招聘-安全試題答案詳細解釋

原文來源於:http://blog.csdn.net/qq_29277155/article/details/51628939 謝謝分享!~ 0x00前言 鑑於曾經做過騰訊找招聘-安全技術筆試題目,故留此一記,以作懷念。此外,網上也有公佈的相關的答案,但是其中有些