EMC筆試總結

EMC的筆試總結,最後沒能去EMC,可惜了


1. 97^{59}除以59的餘數是多少。

//答案是38,這個題目考費馬小定理;不過直接硬算也可以。

第一次聽到費馬小定理: 如果一個數p是質數,且a與p互質,則a^(p-1)%p=1(a的p-1次方模p恆等於1)。

所以97^59%59=( (97^58%59)*(97%59) )%59= (1*38)%59 = 38.

//這題目太那個了。。。


2. int a=1000000000, b=2000000000; a=a+b;b=a-b;a=a-b; 最後a,b是多少?

正常交換。


3. 如何判別一個數是unsigned

我選了 a>=0 && -a>=0;但據說正確答案是 a>=0 && ~a>=0

4. 100層樓,兩個雞蛋。某層之上扔雞蛋就會碎。問至少要測試多少次才能試出這個層數。

動態規劃,答案是14。這個問題討論很多了。

具體方法是先從14樓開始拋第一次;如果沒碎,再從27樓拋第二次;如果還沒碎,再從39樓拋第三次;如果還沒碎,再從50 樓拋第四次;如此,每次間隔的樓層少一層。這樣,任何一次拋棋子碎時,都能確保最多拋14次可以找出臨界樓層。


5. 25匹馬,每次比賽可選5匹馬賽出次序(無法計時)。問至少要比賽多少次才能確定跑得最快,次快和第三快的三匹馬。

7次。首先分爲5組,每組進行一次比賽,然後每組的頭一名共五匹馬比賽一次。假設第一組快於第二組快於第三組依次。最後一次安排第一組的二三名和第二組的一二名和第三組的第一名。


6. 上臺階,每次可走一臺階和兩臺階,問上10個臺階有多少種走法
斐波那契數列。答案89


A、B、C三個瓶子,A瓶子是空的,B瓶子裏有1個白球1個黑球,C瓶子裏有1000個白球和1280個黑球。現在蒙着眼睛從C瓶子裏取兩個球放到A瓶子裏。分兩個階段從三個瓶子中摸球(每次摸球后放回再摸下一次),摸到白球贏55000美元,摸到黑球什麼也得不到也不損失什麼。問爲了使兩次的收益最大,應該採取什麼策略?

算了一下答案應該是兩次都在B裏面拿。

//不知道題目什麼意思


算法題目:

大題1:插入一個節點到一個有序鏈表。

大題2:循環的有序數組(比如1,2,3,4,5,-3,-2,-1這種數列)裏查找一個數


大題3:在一個正整數序列中求和最大的非相鄰子序列(序列任兩元素在原序列裏都不相鄰)


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



//不相鄰整數和
inline int max(int a,int b){return a>b?a:b;}

int sum(int * a,int n)
{
    int dp[n+1];
    memset(dp,0,sizeof(dp)) ;
    dp[1]=a[0];
    for(int i = 1; i< n;++i)
    {
        dp[i+1]=max(dp[i],dp[i-1]+a[i]);
        if(dp[i+1]==dp[i])a[i]=0;
    }
    return dp[n];
}

int main()
{
    int a[]={3,2,4,1,3,5,2};
    printf("%d\n",sum(a,7));
    int i = 6;
    while(i>=0){
        if(a[i]==0){--i;continue;}
        printf("%d\n",a[i]);
        i-=2;
    }
}

 1. 火星上到處是硬幣,隨便拿起一個,如果是頭朝下的就翻成字朝上的,如果是字朝上

的就拋出,落地後有各一半的機會頭朝上或字朝上。再隨便拿起包括剛纔那個在內的

所有硬幣中的一個,重複前述步驟。問,很多很多次後字朝上和頭朝上的硬幣比例?

 

類似的題目:地上有很多硬幣,有很多機器人在處理硬幣,如果是反面,就把硬幣翻轉;如

果是正面就隨機拋一下,一直進行下去,問最後地上硬幣正反面的比例如何?

 

solution:

設最後平衡狀態,有x個反面,y個正面,然後進行上面的操作,得到x+1/2y個正面,

1/2y個反面。列個方程x:y = 1/2y : (x+1/2y),可以得到x:y = 1:2


//my solution:

假設t時刻有x個正面,y個反面,則t+1時刻有x/2+y正面,x/2反面。

則t+1時刻由正面變成反面的硬幣數量爲x/2,由反面變成正面的硬幣數量爲y。

由於最後達到平衡狀態(即正反硬幣數量不在變化)則兩邊相互轉化的硬幣數量應該相等(即正面硬幣變成反面硬幣的數量等於反面硬幣變成正面硬幣的數量),所以有x/2=y ,即x:y=2:1

4.經過最少多少次比較能找出1000個元素中second smallest的一個

n + lgn - 2

//n-1
  times comparison for finding the smallest element.
// the second smallest elements must be among the elements that are compared with smallest element and lose the match. there are at most lgn elements that are compared with smallest element so at most [lgn]-1 times comparisons are required to find the smallest element in the lgn elements which is the second smallest element in the whole set.
5: 10個口袋每個有100個金幣,其中一個口袋每個金幣9grams,其餘正常的金幣都是10grams。有個天平,問最少幾次可以找出那個口袋                                    
10個口袋依次取 0 1 2 3 4 5 6 7 8 9 個金幣,稱一次看看比 9*10/2*10 缺多少就知道了
//不變量題目:不變量=(0+9) /2*10*10,0-9每個變量k的權重是k*10。真實值與不變量差值爲k*10,即可求得k。

同類題目如:1-100中少了一個數,求該數。
//同樣,1-100不變量爲(1+100)/2*100,1-100每個元素k的權重是k,真實值與不變量的差值是k,即可求得少了的數。

6. 實驗室裏有1000個一模一樣的瓶子,但是其中的一瓶有毒。可以用實驗室的小白鼠來

測試哪一瓶是毒藥。如果小白鼠喝掉毒藥的話,會在一個星期的時候死去,其他瓶子裏的

藥水沒有任何副作用。請問最少用多少隻小白鼠可以在一個星期以內查出哪瓶是毒藥


10

//1000個瓶子,用二進制編碼,即0000000001~11111101000。然後給老鼠編號1-10,1號老鼠喝瓶子編號第一位是1的瓶子。2號老鼠喝瓶子編號第二位爲1的瓶子,以此類推。假設3,4,5號老鼠死了,即第0000011100=28號瓶子有毒。因爲只有28號瓶子被3,4,5號老鼠同時喝了。


思考:這個題目是個編號題目,如果1000個瓶子用10進制一一編號則需1000個老鼠一一對應 ,如果用二進制編號則需要10個老鼠多對對一。所以需要多個老鼠同時喝一瓶水才能找到那個瓶子。

7.碗裏有n根麪條,現在一次在碗中取任意兩頭(未必是同一根麪條的)連在一起,直到

沒有面條的剩下爲止,問平均可以在碗裏形成多少個圈?

sum(1/(2i-1)) (i=1,2,...n)

概率問題:n個麪條,2n個頭,一次取2個頭取到相同麪條的概率是1/2n*1/(2n-1)*n*2   //第一次取個頭概率1/2n,第二次取個頭概率1/(2n-1),有n個麪條,並且麪條的兩頭順序可以交換,所以乘2。

則不在一條線的的概率是1-1/(2n-1)=(2n-2)/(2n-1)。

設f(n)表示n個麪條產生的圈,則:

f(n)=1/(2n-1)*(f(n-1)+1)+(2n-2)/(2n-1)*f(n-1)    //1/(2n-1)的概率可以在f(n-1)基礎上增加一個圈,(2n-2)/(2n-1)概率不能在f(n-1)基礎上增加一個圈。

所以f(n)-f(n-1)=1/(2n-1)。則f(n)=sum(1/(2i-1)) i=1,2,3,4..n


思考:典型的概率問題。取兩個頭有兩種情況:

1. 兩個頭在一個麪條上,則可以增加一個圈

2. 兩個頭不在一個麪條上,不能增加圈

產生遞歸公式:f(n) = P(1)*(g( f(n-1) )) + P(2)*( h(f(n-1)) )    //1情況下圈數量+2情況下的圈數量。對取任意兩頭事件的一個全分割。


一些智力題目:

1. Four people are in a group
Alice says,”Exactly one of us is lying.”
Bob says, ”Exactly two of us are lying.”
Charles says, “Exactly three of us are lying.”
Dick says, “All four of us are lying.”
How many people in this group are lying?

A. 0
B. 1
C. 2
D. 3 
E. 4

Answer; D

典型的排除法:一個個選項和題目說明相比較

如果選A,則那麼四個人都說謊了,應該是4個說謊,不對

如果選B,那麼B,C,D都說謊了,應該是3個說謊,不對

如果選C,那麼A,C,D都說謊了,應該3個說謊,不對

如果選D,那麼A,B,D都說謊,3個說謊,這個對的。

如果選E,則A,B,C說謊,應該3個說謊,不對


2. Allen and Brenda, both have a note stuck on their forehead, with a positive
integer number
written on it .Both Allen and Brenda can see each other’s number. They also k
now that the two
numbers have a difference of one. They are trying to figure out the number on
their own forehead.

Allen first says,”I don’t know my number.”
Brenda says,” I don’t know my number either”
Then Allen says “Now, I know my number”
Brenda now says, “Yeah, I know my number also!”
What is the number of Allen and Brenda?

A. 2,1
B. 1,2
C. 3,2
D. 2,3
E. 4,3

Answer: C

思考:同樣用排除法。一個個嘗試

A:2.1。 因爲兩個人都是正數,所以如果一方是1個話另一方馬上就可以知道自己是2,因爲不會是0。排除

B:1,2. 原因同A,排除

C:3,2。 A看到B是2,所以A可能是1或者3,但是A不知道。同樣B看到A是3,所以知道自己是2或者4,同樣不確定。

但是因爲B說自己不知道自己的數字,所以A馬上知道了自己一定不是1,因爲如果A是1,那麼B馬上能知道自己的數字是2,但是B不知道,所以A就可以知道自己是3.

同樣一旦A知道了自己是3,那麼B馬上知道了自己是2,因爲只有是2才能使A確定自己是3.

D:2,3。順序反了,因爲是A先說自己知道了,但是A沒法知道,都由B先知道,因爲2在A這邊

E: 4,3。兩個人都沒法知道。


3. Two kinds of chemical material are stored in six buckets(each bucket has o
nly one kind of
chemical). The volumes of these buckets are: 8L, 13L, 15L, 17L, 19L and 31L. I
t is also known
that the price of one chemical is twice that of the other. A man has purchased
five of the buckets,
and found that he spent the same amount money on each kind of chemical. Which
bucket was left
unsold?

A. 8L
B. 13L
C. 15L
D. 17L
E. 19L

Answer: E

排除法:一個個嘗試。去點一個bucket,然後剩下的5箇中的三個是另外二個的的兩倍體積即可。(當然4個對一個也是可以的,但是這道題目不行)

只能憑耐心,不要出錯。

1、兩個人往圓桌上放硬幣,最後誰沒有地方放,誰就爲輸家。你先放,請問有致勝方法嗎?

solution: 這道題目有致勝的方法。

致勝的策略就是你將第一顆硬幣放在圓桌的中心,然後對方放一顆,你就一圓桌中心爲對稱點

的另一側放一顆硬幣。這樣就可以保準自己永遠有地方放。最後對方一定是先沒有地方放的。

此時桌面上的硬幣數量個數爲奇數。

PS:此題有一個引申的題目,

一個N*N的對稱矩陣,每行每列都是數字1~N的一種全排列。例如:
  1 2     1 2 3
  2 1     2 3 1
        3 1 2
注意,3*3矩陣的一條對角線也是1、2、3的一個全排列,而2*2的矩陣則不是。請問,

什麼樣的N,能使N*N的矩陣在滿足題目條件的情況下必然有一條對角線是1~N的一個全排列。
  A.3的冪
  B.奇數
  C.除了2以外的質數
  D.N=3
  E.以上全對

此題答案爲B.


//第二道題目在編程之美上有
2、有兩堆東西,一份有4個、一份有7個,兩個人開始拿東西,一次可拿任意多個,但只能

從一份中拿。現規定:如果最後剩下1個,而且輪到誰拿誰就輸了,現在你先拿,請問有致

勝方法嗎?
solution: 

first one:       0000

second one:  0000000

採取的策略也很簡單,第一次取的時候從七個裏面取三個,讓兩堆的數量相等,然後分情況討論

1. 對方從另一堆取1,2個時從另外一堆取同樣的個數。當你發現某一堆只剩下一個,就將另一

堆所有的都取走。

2. 如果對方一次從一堆中取3個,你就將另一堆的所有都取走

3.如果對方一次從一堆中取4個,你就從另外一堆取走3個


異或是個很好的工具,存在差異就可以異或。

e = 2.71828183,e^0.5 = 1.6462077633154327947670181628178

pi = 3.14159265, pi^0.5 = 1.77245

優先級翻轉(Priority Inversion,是指某同步資源被較低優先級的進程/線程所擁有,較高優先級的進程/線程競爭該同步資源未獲得該資源,而使得較高優先級進程/線程反而推遲被調度執行的現象。

在設計多線程程序時候,避免優先級翻轉的最簡單方法,就是不要讓不同優先級的線程去競爭同一個同步資源。

http://blog.csdn.net/thl789/article/details/617629


emc筆試2011-9-25
1. kernel可以訪問所有的系統內存嗎?
可以,對於高端內存建立永久映射或者臨時映射都可以訪問。
2. kernel中可以調用syscall嗎?
這個還真沒注意過,感覺完全取決於軟中斷指令int 80的語義。可以。
3. 在kernel中,一個線程獲得了spinlock,那麼這個線程可以被interrupt嗎?
可以,spinlock 並沒有關中斷,貌似spinlock_irqsave 才關中斷了。


class Test{
};

int main(){
    const Test & t = Test();    //可以通過,臨時對象是右值,只能賦給const的引用,因爲臨時對象沒地址
    Test & t = Test();            //通不過。臨時對象不是左值,不能賦給非const引用。
}

引用不能指向臨時對象的原因我覺得是臨時對象被自動析構後引用就成了dangling reference了,會有異常。
引用可以指向無名對象,但必須是const的引用,因爲無名對象是const的。

char a[]="abcd";
char * p = a;
p+2=a        //錯誤
p[-1]=32;    //可以通過編譯並運行
p[4]=a[2];   //可以通過編譯並運行


database transaction : atomic, consistent, isolated and durable.
kernel cannot access to libc
file metadata has no filename
spinlock is lighter than mutex. no cpu consumption when one process waits for the mutex.

spinlock holder can be interrupted?    //spinlock can be interrupted but interrupt spinlock might cause deadlock so we need disable local interrupt.
kernel can access to all memory?      //still in search,no answer

kernel can call syscall?

int dup(int fd),將fd複製給新的fd,新的fd是最小的沒有使用的fd編號。
int dup2(int fd1,int fd2):將fd1複製爲fd2,如果fd2原先打開,則先關閉。

使用fcntl進行復制,F_DUPFD,
fcntl可以獲得/設置文件標誌位,文件鎖等。

ioctl用來訪問設備的。

sql中5/null的結果是null

interface derivation and implementation derivation:
interface derivation is a much better oo design. a group of rules to be followed by its implementers.


多選題1:
#define abc(s,m) (size_t)&(((s*)0)->m)
#define bcd(ptr,type,member) ({                             \
        const typeof(((type*)0)->member) * __mptr = (ptr);  \
        (type*)((char*)__mptr - abc(type,member));})
//abc是取結構體s裏面成員m相對於結構體s頭部的偏移
//bcd是取結構體type的頭部
//這兩個取自linux內核的list數據結構實現。

struct test{
    int a;
    char b;        padding是放在b後面的,不是放在c後面的,要注意
    long c;
};

int main()
{
    struct test t;
    t.a=-1;
    t.c =31;
    struct test * p ;
    p = bcd(&(t.c),struct test,c);    //其實bcd就是把t.c這個成員所在的結構體頭部地址返回。
    printf("%ld\n",p->c);        //輸出31。
    return 0;
}

多選題2:

int main{
    char buf[4];
    int x = 345;
    sprintf(buf,"%s","abcdef");    //buf只有4個字節,ef把後面的x沖掉了。
    buf[4]=0;
    buf[3]='k';
    printf("%d,%s\n",x,buf);    //輸出    26112,abck
    return 0;
}

寫一個可增可減的hash函數:
//n:輸入id
//m:hash表大小
//diff:哈希表大小變化值,增加或者減少diff個長度
int hash(int n,int m, int diff)
{
    return (n%m - n/m*diff)%(diff+m)    //(原來的對應格子號-變化的格子數)%變化後的hash表大小
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章