【劍指offer】撲克牌的順子
轉載請註明出處:http://blog.csdn.net/ns_code/article/details/27849055
- 題目描寫敘述:
LL今天心情特別好,由於他去買了一副撲克牌,發現裏面竟然有2個大王,2個小王(一副牌原本是54張^_^)...他隨機從中抽出了5張牌,想測測自己的手氣,看看能不能抽到順子,假設抽到的話,他決定去買體育彩票,嘿嘿!。“紅心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是順子.....LL不高興了,他想了想,決定大\小 王能夠看成不論什麽數字,並且A看作1,J為11,Q為12,K為13。上面的5張牌就能夠變成“1,2,3,4,5”(大小王分別看作2和4),“So Lucky!”
LL決定去買體育彩票啦。
如今,要求你使用這幅牌模擬上面的過程,然後告訴我們LL的運氣怎樣。為了方便起見,你能夠覺得大小王是0。
- 輸入:
輸入有多組數據。
每組數據包括兩行,第一行輸入一個正數n(0<=n<=14),表示從撲克牌中抽出的撲克牌數。接下來的一行輸入n個數,表示從這幅撲克牌中抽出的牌。假設n=0,則結束輸入。
- 輸出:
相應每組數據,假設抽出的牌是順子,則輸出“So Lucky!”。否則,輸出“Oh My God!”。
- 例子輸入:
5 3 5 1 0 4 5 3 5 4 7 6 5 3 5 7 4 8 0
- 例子輸出:
So Lucky! So Lucky! Oh My God!
看論壇裏面好多人吐槽。
總之,無論那麽多。這道題目無論它怎麽坑爹,用劍指offer上的思路寫的代碼AC是沒問題的,由於這裏無論你0有多少個(僅僅要不大於數組的長度就可)都OK。
我之前想避開排序。或者開辟哈希數組,就遍歷一遍求出最大值。最小值。0出現的次數,而後依據三者間的關系來推斷是否構成順子,但這要在數組中沒有反復元素的前提下。而要推斷數組中沒有反復元素,要麽要排序,要麽就要借助哈希數組統計元素出現的次數,終於還是省不掉。
無奈最後還是用書上的思路。為求代碼的簡潔性,一樣用C語言自帶的高速排序函數。當然用計數排序(事實上跟開辟哈希數組就是一個思路)更快點,但對n最大為14的情況。二者效率差不了太多。
AC代碼:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<stdbool.h> int mycompare(const void *data1,const void *data2) { return *(int *)data1 - *(int *)data2; } bool IsContinuous(int *arr,int len) { if(arr==NULL || len<1) return false; qsort(arr,len,sizeof(int),mycompare); int NumOf0 = 0; //0的個數 int NumOfGap = 0; //空缺的個數 int i; for(i=0;i<len-1;i++) { if(arr[i] == 0) NumOf0++; else { if(arr[i] == arr[i+1]) return false; else NumOfGap += arr[i+1]-arr[i]-1; } } return (NumOfGap>NumOf0)?false:true; } int main() { int n; int arr[15]; memset(arr,0,sizeof(arr)); while(scanf("%d",&n)!=EOF && n!=0) { int i; for(i=0;i<n;i++) scanf("%d",arr+i); bool can = IsContinuous(arr,n); if(can) printf("So Lucky!\n"); else printf("Oh My God!\n"); } return 0; }
/**************************************************************
Problem: 1355
User: mmc_maodun
Language: C
Result: Accepted
Time:0 ms
Memory:912 kb
****************************************************************/
【劍指offer】撲克牌的順子