題目一
煤球數目
有一堆煤球,堆成三角棱錐形。具體:
第一層放1個,
第二層3個(排列成三角形),
第三層6個(排列成三角形),
第四層10個(排列成三角形),
....
如果一共有100層,共有多少個煤球?
請填表示煤球總數目的數字。
注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。
答案:171700
解析:
方法一:數學方法
方法二:暴力循環
易知每一層的數目都是上一層煤球數加上這一層的層數,代碼如下:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 5 int main() 6 { 7 int i=0,sum=0,num=0; 8 //sum是煤球總數,num是當前層煤球數 9 for(i=1;i<=100;i++) 10 { 11 num+=i; 12 sum+=num; 13 } 14 printf("%d\n",sum); 15 return 0; 16 }

題目二
生日蠟燭
某君從某年開始每年都舉辦一次生日party,並且每次都要吹熄與年齡相同根數的蠟燭。
現在算起來,他一共吹熄了236根蠟燭。
請問,他從多少歲開始過生日party的?
請填寫他開始過生日party的年齡數。
注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。
答案:26
解析:
暴力枚舉,代碼如下:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 5 int main() 6 { 7 int i,j,num; 8 //設某君從i歲開始過生日,現在j歲 9 //num是吹滅掉蠟燭數 10 for(i=0;i<200;i++) 11 { 12 for(j=0;j<200;j++) 13 { 14 num=(i+j)*(j-i+1)/2; 15 if(num==236) 16 { 17 printf("%d\n",i); 18 break; 19 } 20 } 21 } 22 return 0; 23 }

題目三
湊算式

這個算式中A~I代表1~9的數字,不同的字母代表不同的數字。
比如:
6+8/3+952/714 就是一種解法,
5+3/1+972/486 是另一種解法。
這個算式一共有多少種解法?
注意:你提交應該是個整數,不要填寫任何多余的內容或說明性文字。
答案:29
解析:
方法一:遞歸法/DFS法,請自行百度
方法二:暴力枚舉,注意每個字母代表的數字都不一樣。代碼如下:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 5 int main() 6 { 7 int a[9];//a[0]~a[8]代表A-I 8 int sum=0; 9 double num=0; 10 for(a[0]=1;a[0]<=9;a[0]++) 11 { 12 for(a[1]=1;a[1]<=9;a[1]++) 13 { 14 if(a[1]==a[0]) 15 continue; 16 for(a[2]=1;a[2]<=9;a[2]++) 17 { 18 if(a[2]==a[1]||a[2]==a[0]) 19 continue; 20 for(a[3]=1;a[3]<=9;a[3]++) 21 { 22 if(a[3]==a[2]||a[3]==a[1]||a[3]==a[0]) 23 continue; 24 for(a[4]=1;a[4]<=9;a[4]++) 25 { 26 if(a[4]==a[3]||a[4]==a[2]||a[4]==a[1]||a[4]==a[0]) 27 continue; 28 for(a[5]=1;a[5]<=9;a[5]++) 29 { 30 if(a[5]==a[4]||a[5]==a[3]||a[5]==a[2]||a[5]==a[1]||a[5]==a[0]) 31 continue; 32 for(a[6]=1;a[6]<=9;a[6]++) 33 { 34 if(a[6]==a[5]||a[6]==a[4]||a[6]==a[3]||a[6]==a[2]||a[6]==a[1]||a[6]==a[0]) 35 continue; 36 for(a[7]=1;a[7]<=9;a[7]++) 37 { 38 if(a[7]==a[6]||a[7]==a[5]||a[7]==a[4]||a[7]==a[3]||a[7]==a[2]||a[7]==a[1]||a[7]==a[0]) 39 continue; 40 for(a[8]=1;a[8]<=9;a[8]++) 41 { 42 if(a[8]==a[7]||a[8]==a[6]||a[8]==a[5]||a[8]==a[4]||a[8]==a[3]||a[8]==a[2]||a[8]==a[1]||a[8]==a[0]) 43 continue; 44 num=(double)a[0]+(double)a[1]/a[2]+(double)(a[3]*100+a[4]*10+a[5])/(a[6]*100+a[7]*10+a[8]); 45 if(num==10.0) 46 { 47 sum++; 48 } 49 } 50 } 51 } 52 } 53 } 54 } 55 } 56 } 57 } 58 printf("%d\n",sum); 59 return 0; 60 }

題目四
快速排序
排序在各種場合經常被用到。
快速排序是十分常用的高效率的算法。
其思想是:先選一個“標尺”,
用它把整個隊列過一遍篩子,
以保證:其左邊的元素都不大於它,其右邊的元素都不小於它。
這樣,排序問題就被分割為兩個子區間。
再分別對子區間排序就可以了。
下面的代碼是一種實現,請分析並填寫划線部分缺少的代碼。
1 #include <stdio.h> 2 3 void swap(int a[], int i, int j) 4 { 5 int t = a[i]; 6 a[i] = a[j]; 7 a[j] = t; 8 } 9 10 int partition(int a[], int p, int r) 11 { 12 int i = p; 13 int j = r + 1; 14 int x = a[p]; 15 while(1){ 16 while(i<r && a[++i]<x); 17 while(a[--j]>x); 18 if(i>=j) break; 19 swap(a,i,j); 20 } 21 ______________________; 22 return j; 23 } 24 25 void quicksort(int a[], int p, int r) 26 { 27 if(p<r){ 28 int q = partition(a,p,r); 29 quicksort(a,p,q-1); 30 quicksort(a,q+1,r); 31 } 32 } 33 34 int main() 35 { 36 int i; 37 int a[] = {5,13,6,24,2,8,19,27,6,12,1,17}; 38 int N = 12; 39 40 quicksort(a, 0, N-1); 41 42 for(i=0; i<N; i++) printf("%d ", a[i]); 43 printf("\n"); 44 45 return 0; 46 }
注意:只填寫缺少的內容,不要書寫任何題面已有代碼或說明性文字。
答案:swap(a,p,j)
可驗證的完整代碼如下:
1 #include <stdio.h> 2 3 void swap(int a[], int i, int j) 4 { 5 int t = a[i]; 6 a[i] = a[j]; 7 a[j] = t; 8 } 9 10 int partition(int a[], int p, int r) 11 { 12 int i = p; 13 int j = r + 1; 14 int x = a[p]; 15 while(1){ 16 while(i<r && a[++i]<x); 17 while(a[--j]>x); 18 if(i>=j) break; 19 swap(a,i,j); 20 } 21 //______________________; 22 swap(a,p,j); 23 return j; 24 } 25 26 void quicksort(int a[], int p, int r) 27 { 28 if(p<r){ 29 int q = partition(a,p,r); 30 quicksort(a,p,q-1); 31 quicksort(a,q+1,r); 32 } 33 } 34 35 int main() 36 { 37 int i; 38 int a[] = {5,13,6,24,2,8,19,27,6,12,1,17}; 39 int N = 12; 40 41 quicksort(a, 0, N-1); 42 43 for(i=0; i<N; i++) printf("%d ", a[i]); 44 printf("\n"); 45 46 return 0; 47 }

題目五
抽簽
X星球要派出一個5人組成的觀察團前往W星。
其中:
A國最多可以派出4人。
B國最多可以派出2人。
C國最多可以派出2人。
....
那么最終派往W星的觀察團會有多少種國別的不同組合呢?
下面的程序解決了這個問題。
數組a[] 中既是每個國家可以派出的最多的名額。
程序執行結果為:
DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
BCFFF
BCEFF
BCDFF
BCDEF
....
(以下省略,總共101行)
1 #include <stdio.h> 2 #define N 6 3 #define M 5 4 #define BUF 1024 5 6 void f(int a[], int k, int m, char b[]) 7 { 8 int i,j; 9 10 if(k==N){ 11 b[M] = 0; 12 if(m==0) printf("%s\n",b); 13 return; 14 } 15 16 for(i=0; i<=a[k]; i++){ 17 for(j=0; j<i; j++) b[M-m+j] = k+'A'; 18 ______________________; //填空位置 19 } 20 } 21 int main() 22 { 23 int a[N] = {4,2,2,1,1,3}; 24 char b[BUF]; 25 f(a,0,M,b); 26 return 0; 27 }
仔細閱讀代碼,填寫划線部分缺少的內容。
注意:不要填寫任何已有內容或說明性文字。
答案:f(a,k+1,m-i,b) 或者 f(a,k+1,m-j,b)
代碼填空題完成后代入完整程序進行驗證是最好的檢驗方法。
可驗證的完整代碼如下:
1 #include <stdio.h> 2 #define N 6 3 #define M 5 4 #define BUF 1024 5 6 void f(int a[], int k, int m, char b[]) 7 { 8 int i,j; 9 10 if(k==N){ 11 b[M] = 0; 12 if(m==0) printf("%s\n",b); 13 return; 14 } 15 16 for(i=0; i<=a[k]; i++){ 17 for(j=0; j<i; j++) b[M-m+j] = k+'A'; 18 f(a,k+1,m-i,b) ; //填空位置 19 } 20 } 21 int main() 22 { 23 int a[N] = {4,2,2,1,1,3}; 24 char b[BUF]; 25 f(a,0,M,b); 26 return 0; 27 }

題目六
方格填數
如下的10個格子
填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)
一共有多少種可能的填數方案?
請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。
答案:1580
解析:http://www.cnblogs.com/xiangguoguo/p/5339605.html
1 #include<stdio.h> 2 #include<stdlib.h> 3 int count=0; 4 int take[10],index=0;//記錄當前已經填入的數字,用於填數字前判斷是否已經使用,避免重復使用 5 int is_legal(int s[3][4])//判斷是否滿足要求:相鄰位置數字不能相鄰,就是兩數字的差大於1.就是為什么s[0][0]、s[2][3]置為-2; 6 { 7 //這里的判斷方法有點死板。假設每個位置都有上下左右和對角,只需要判斷這些位置 8 //是不是在數組中,在就進行比較,不在就說明沒有。 9 for(int i=0;i<3;i++) 10 { 11 for(int j=0;j<4;j++) 12 { 13 if(j-1>=0) 14 { 15 if(abs(s[i][j]-s[i][j-1])==1) 16 { 17 return 0; 18 } 19 } 20 if(j+1<4) 21 { 22 if(abs(s[i][j]-s[i][j+1])==1) 23 { 24 return 0; 25 } 26 } 27 if(i+1<3) 28 { 29 if(abs(s[i][j]-s[i+1][j])==1) 30 { 31 return 0; 32 } 33 } 34 if(j-1>=0&&i+1<3) 35 { 36 if(abs(s[i][j]-s[i+1][j-1])==1) 37 { 38 return 0; 39 } 40 } 41 if(j+1<4&&i+1<3) 42 { 43 if(abs(s[i][j]-s[i+1][j+1])==1) 44 { 45 return 0; 46 } 47 } 48 if(i-1>=0&&j+1<4) 49 { 50 if(abs(s[i][j]-s[i-1][j+1])==1) 51 { 52 return 0; 53 } 54 } 55 if(i-1>=0) 56 { 57 if(abs(s[i][j]-s[i-1][j])==1) 58 { 59 return 0; 60 } 61 } 62 if(j-1>=0&&i-1>=0) 63 { 64 if(abs(s[i][j]-s[i-1][j-1])==1) 65 { 66 return 0; 67 } 68 } 69 } 70 } 71 return 1; 72 } 73 void fun(int s[3][4],int a,int b) 74 { 75 int i; 76 if(a==2&&b==3)//表示當前已經填滿了表格,需要進行判斷看是否滿足要求 77 { 78 if(is_legal(s)) 79 { 80 count++; 81 } 82 } 83 else//繼續填寫 84 { 85 for(i=0;i<=9;i++) 86 { 87 int j; 88 for(j=0;j<index;j++)//填寫的數字必須是沒有用過的 89 { 90 if(i==take[j]) 91 { 92 break; 93 } 94 } 95 if(j==index) 96 { 97 s[a][b]=i; 98 take[index++]=i; 99 if(b<3)//表示當前行還沒填完 100 { 101 fun(s,a,b+1); 102 } 103 else//當前行填完就從下一行開始 104 { 105 if(a<2)//判斷當前行是否是最后一行 106 { 107 fun(s,a+1,0); 108 } 109 } 110 index--;//在一次填滿結束后,當前位置的數字換為其他可以填寫的數字 111 //所以當前使用的數字需要出去。 112 } 113 } 114 } 115 } 116 int main() 117 { 118 int s[3][4]; 119 s[0][0]=-2; 120 s[2][3]=-2; 121 //左上角和右下角沒有,為了方便判斷把數值設為-2(小於-1大於10均可) 122 fun(s,0,1); 123 printf("%d\n",count); 124 return 0; 125 }
題目七
剪郵票

如【圖1.jpg】, 有12張連在一起的12生肖的郵票。
現在你要從中剪下5張來,要求必須是連着的。
(僅僅連接一個角不算相連)
比如,【圖2.jpg】,【圖3.jpg】中,粉紅色所示部分就是合格的剪取。


請你計算,一共有多少種不同的剪取方法。
請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。
答案:116
解析:http://www.cnblogs.com/program-ccc/p/5321243.html
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 int a[3][4]={ 5 {0,1,2,3}, 6 {4,5,6,7}, 7 {8,9,10,11}};//為了方便,均執行-1操作 8 int vec[15]; 9 int res; 10 int dx[4]={1,0,-1,0}; 11 int dy[4]={0,1,0,-1}; 12 int vis[5][5]; 13 bool Include(int x) 14 { 15 for(int i=0;i<5;i++) 16 if(vec[i]==x) return true; 17 return false; 18 } 19 void Connect(int y,int x) 20 { 21 for(int i=0;i<4;i++) 22 { 23 int ny=dy[i]+y; 24 int nx=dx[i]+x; 25 if(0<=ny&&ny<3&&0<=nx&&nx<4&&!vis[ny][nx]&&Include(a[ny][nx])) 26 { 27 vis[ny][nx]=1; 28 Connect(ny,nx); 29 } 30 } 31 } 32 void dfs(int i,int j) 33 { 34 if(i==12) 35 { 36 if(j==5) 37 { 38 memset(vis,0,sizeof(vis)); 39 int y=vec[0]/4,x=vec[0]%4; 40 vis[y][x]=1; 41 Connect(y,x); 42 int mark=0; 43 for(int k=0;k<j;k++) 44 { 45 y=vec[k]/4; 46 x=vec[k]%4; 47 if(vis[y][x]==1) 48 mark++; 49 } 50 if(mark==5) res++; 51 } 52 return ; 53 } 54 vec[j]=*(a[0]+i); 55 dfs(i+1,j+1); 56 vec[j]=0; 57 dfs(i+1,j); 58 } 59 60 int main() 61 { 62 res=0; 63 dfs(0,0); 64 printf("%d\n",res); 65 return 0; 66 }
題目八
四平方和
四平方和定理,又稱為拉格朗日定理:
每個正整數都可以表示為至多4個正整數的平方和。
如果把0包括進去,就正好可以表示為4個數的平方和。
比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符號表示乘方的意思)
對於一個給定的正整數,可能存在多種平方和的表示法。
要求你對4個數排序:
0 <= a <= b <= c <= d
並對所有的可能表示法按 a,b,c,d 為聯合主鍵升序排列,最后輸出第一個表示法
程序輸入為一個正整數N (N<5000000)
要求輸出4個非負整數,按從小到大排序,中間用空格分開
例如,輸入:
5
則程序應該輸出:
0 0 1 2
再例如,輸入:
12
則程序應該輸出:
0 2 2 2
再例如,輸入:
773535
則程序應該輸出:
1 1 267 838
資源約定:
峰值內存消耗 < 256M
CPU消耗 < 3000ms
請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多余內容。
所有代碼放在同一個源文件中,調試通過后,拷貝提交該源碼。
注意: main函數需要返回0
注意: 只使用ANSI C/ANSI C++ 標准,不要調用依賴於編譯環境或操作系統的特殊函數。
注意: 所有依賴的函數必須明確地在源文件中 #include <xxx>, 不能通過工程設置而省略常用頭文件。
提交時,注意選擇所期望的編譯器類型。
解析:http://blog.csdn.net/luoluozlb/article/details/51339287
1 #include <stdio.h> 2 #include <math.h> 3 4 int main() 5 { 6 int a, b, c, n, flag = 0; 7 double maxN, d; 8 scanf("%d", &n); 9 maxN = sqrt((double)n); 10 11 for(a = 0; a <= maxN; a ++){ 12 for(b = a; b <= maxN; b ++){ 13 for(c = b; c <= maxN; c ++){ 14 d = sqrt((double)(n - a*a - b*b - c*c)); 15 if(d == (int)d){ 16 printf("%d %d %d %d\n", a, b, c, (int)d); 17 flag = 1; 18 break; 19 } 20 } 21 if(flag) 22 break; 23 } 24 if(flag) 25 break; 26 } 27 return 0; 28 }
題目九
交換瓶子
有N個瓶子,編號 1 ~ N,放在架子上。
比如有5個瓶子:
2 1 3 5 4
要求每次拿起2個瓶子,交換它們的位置。
經過若干次后,使得瓶子的序號為:
1 2 3 4 5
對於這么簡單的情況,顯然,至少需要交換2次就可以復位。
如果瓶子更多呢?你可以通過編程來解決。
輸入格式為兩行:
第一行: 一個正整數N(N<10000), 表示瓶子的數目
第二行:N個正整數,用空格分開,表示瓶子目前的排列情況。
輸出數據為一行一個正整數,表示至少交換多少次,才能完成排序。
例如,輸入:
5
3 1 2 5 4
程序應該輸出:
3
再例如,輸入:
5
5 4 3 2 1
程序應該輸出:
2
資源約定:
峰值內存消耗 < 256M
CPU消耗 < 1000ms
請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多余內容。
所有代碼放在同一個源文件中,調試通過后,拷貝提交該源碼。
注意: main函數需要返回0
注意: 只使用ANSI C/ANSI C++ 標准,不要調用依賴於編譯環境或操作系統的特殊函數。
注意: 所有依賴的函數必須明確地在源文件中 #include <xxx>, 不能通過工程設置而省略常用頭文件。
提交時,注意選擇所期望的編譯器類型。
解析:http://blog.csdn.net/luoluozlb/article/details/51339307
1 #include <stdio.h> 2 #include <math.h> 3 4 int main() 5 { 6 int arr[10010]; //記錄第i個瓶子編號為多少 7 int flag[10010]; //記錄編號為i的瓶子在哪兒 8 int ans = 0; 9 int n,i; 10 scanf("%d",&n); 11 12 for(i = 1 ; i <= n ; i ++) 13 scanf("%d",&arr[i]); 14 15 for(i = 1 ; i <= n ; i ++ ) 16 flag[arr[i]] = i; 17 18 for(i = 1 ; i <= n ; i ++) 19 { 20 if( i != arr[i] ) 21 { 22 int x = arr[i]; 23 arr[i] ^= arr[flag[i]] ^= arr[i] ^= arr[flag[i]]; 24 flag[i] ^= flag[x] ^= flag[i] ^= flag[x]; 25 ans ++; 26 } 27 } 28 29 printf("%d\n",ans); 30 return 0; 31 }
題目十
最大比例
X星球的某個大獎賽設了M級獎勵。每個級別的獎金是一個正整數。
並且,相鄰的兩個級別間的比例是個固定值。
也就是說:所有級別的獎金數構成了一個等比數列。比如:
16,24,36,54
其等比值為:3/2
現在,我們隨機調查了一些獲獎者的獎金數。
請你據此推算可能的最大的等比值。
輸入格式:
第一行為數字 N (0<N<100),表示接下的一行包含N個正整數
第二行N個正整數Xi(Xi<1 000 000 000 000),用空格分開。每個整數表示調查到的某人的獎金數額
要求輸出:
一個形如A/B的分數,要求A、B互質。表示可能的最大比例系數
測試數據保證了輸入格式正確,並且最大比例是存在的。
例如,輸入:
3
1250 200 32
程序應該輸出:
25/4
再例如,輸入:
4
3125 32 32 200
程序應該輸出:
5/2
再例如,輸入:
3
549755813888 524288 2
程序應該輸出:
4/1
資源約定:
峰值內存消耗 < 256M
CPU消耗 < 3000ms
請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多余內容。
所有代碼放在同一個源文件中,調試通過后,拷貝提交該源碼。
注意: main函數需要返回0
注意: 只使用ANSI C/ANSI C++ 標准,不要調用依賴於編譯環境或操作系統的特殊函數。
注意: 所有依賴的函數必須明確地在源文件中 #include <xxx>, 不能通過工程設置而省略常用頭文件。
提交時,注意選擇所期望的編譯器類型。
解析:http://www.aichengxu.com/cyvyan/6607933.htm
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 6 long long int a[100],p1[100],p2[100]; 7 8 long long int gcd(long long int a,long long int b) 9 { 10 long long int t; 11 while(t=a%b) 12 { 13 a=b; 14 b=t; 15 } 16 return b; 17 } 18 19 int main() 20 { 21 int n; 22 cin>>n; 23 24 memset(a,0,sizeof(a)); 25 for(int i=0; i<n; i++) 26 { 27 cin>>a[i]; 28 } 29 sort(a,a+n);//從小到大排序 30 int k=1; 31 for(int i=1; i<n; i++)//去掉重復的數字 32 { 33 if(a[i]!=a[i-1]) 34 a[k++]=a[i]; 35 } 36 n=k; 37 if(n==1)//如果只剩下一個數字,則公比為1/1 38 { 39 cout<<"1/1"<<endl; 40 return 0; 41 } 42 else if(n==2)//如果剩下兩個數字,則公比為兩者的商,利用最大公約數求商 43 { 44 long long int g=gcd(a[n-1],a[n-2]); 45 cout<<a[n-1]/g<<"/"<<a[n-2]/g<<endl; 46 } 47 else if(n>2) 48 { 49 k=0; 50 long long int g,g1,g2; 51 for(int i=1; i<n; i++)//分別求出后一項與前一項的比值 52 { 53 g=gcd(a[i],a[i-1]); 54 p1[k]=a[i]/g; 55 p2[k]=a[i-1]/g; 56 k++; 57 } 58 double t=999999; 59 long long int t1,t2,tt1,tt2; 60 61 for(int i=0; i<k; i++)//遍歷每一個比值,用大的除以小的,找出最小的公比 62 for(int j=i+1; j<k; j++) 63 { 64 65 if(p1[i]*p2[j]>p1[j]*p2[i]) 66 { 67 t1=p1[i]/p1[j]; 68 t2=p2[i]/p2[j]; 69 } 70 else if(p1[i]*p2[j]<p1[j]*p2[i]) 71 { 72 t1=p1[j]/p1[i]; 73 t2=p2[j]/p2[i]; 74 } 75 else if(p1[i]*p2[j]==p1[j]*p2[i]) 76 { 77 t1=p1[i]; 78 t2=p2[i]; 79 } 80 if(1.0*t1/t2<t) 81 { 82 t=1.0*t1/t2; 83 tt1=t1; 84 tt2=t2; 85 } 86 } 87 g=gcd(tt1,tt2); 88 cout<<tt1/g<<"/"<<tt2/g<<endl; 89 } 90 91 return 0; 92 }
