藍橋杯練習系統習題-歷年真題解析1(完整版)

文章推薦java

藍橋杯練習系統習題-歷年真題解析1

題目搜索方式:Ctrl+F—-> 輸入題目名稱—>定位到解答.node

入門訓練(詳見 算法-藍橋杯習題(1-1))ios

基礎練習(詳見 算法-藍橋杯習題(2-1))算法

基礎練習(詳見 算法-藍橋杯習題(2-2))編程

算法訓練(詳見 算法-藍橋杯習題(3-1))數組

算法訓練(詳見 算法-藍橋杯習題(3-2))緩存

算法訓練(詳見 算法-藍橋杯習題(3-3))安全

算法訓練(詳見 算法-藍橋杯習題(3-4))網絡

算法訓練(詳見 算法-藍橋杯習題(3-5))app

算法訓練(詳見 算法-藍橋杯習題(3-6))

算法提升(詳見 算法-藍橋杯習題(4-1))

算法提升(詳見 算法-藍橋杯習題(4-2))

歷屆試題(詳見 算法-藍橋杯習題(5-1))

歷屆試題(詳見 算法-藍橋杯習題(5-2))

歷屆試題 核桃的數量

問題描述
小張是軟件項目經理,他帶領3個開發組。工期緊,今天都在加班呢。爲鼓舞士氣,小張打算給每一個組發一袋核桃(據傳言能補腦)。他的要求是:

  1. 各組的核桃數量必須相同

  2. 各組內必須能平分核桃(固然是不能打碎的)

  3. 儘可能提供知足1,2條件的最小數量(節約鬧革命嘛)

    輸入格式
    輸入包含三個正整數a, b, c,表示每一個組正在加班的人數,用空格分開(a,b,c<30)
    輸出格式
    輸出一個正整數,表示每袋核桃的數量。
    樣例輸入1
    2 4 5
    樣例輸出1
    20
    樣例輸入2
    3 1 1
    樣例輸出2
    3

#include <stdio.h> 
 main() 
 { 
 int a,b,c,s; 
 do 
 { 
 scanf("%d%d%d", &a,&b,&c); 
 } 
 while(a>30&&b>30&&c>30); 
 s=f1(a,b); 
 // printf("%d\n",s); 
 s=f1(s,c); 
 printf("%d\n",s); 
 return 0; 
 } 
 int f1(int a,int b) 
 { 
 int t,m; 
 int c; 
 if (a < b) 
 { 
 t = a; 
 a = b; 
 b = t; 
 } 
 m = a * b; 
 c = a % b; 
 while (c != 0) 
 { 
 a = b; 
 b = c; 
 c = a % b; 
 } 
 return m/b;   }  

歷屆試題 打印十字圖

問題描述
小明爲某機構設計了一個十字型的徽標(並不是紅十字會啊),以下所示:

對方同時也須要在電腦dos窗口中以字符的形式輸出該標誌,並能任意控制層數。

輸入格式
一個正整數 n (n<30) 表示要求打印圖形的層數。
輸出格式
對應包圍層數的該標誌。
樣例輸入1
1
樣例輸出1

樣例輸入2
3
樣例輸出2

提示
請仔細觀察樣例,尤爲要注意句點的數量和輸出位置。

#include <cstdlib> 
 #include <iostream> 
 #include <stdio.h> 
 #include <stdlib.h> 
 using namespace std; 
 const 
 int SPACE = '.'; 
 int STAR = '$'; 
 // 獲取每行的字符數 
 int getRowLength(int layerCount)   { 
 return 5 + layerCount * 4; 
 } 
 // 初始化 
 void clearAll(char* buf, int layerCount)   { 
 int size = getRowLength(layerCount); 
 size = size * size; 
 for (int i=0; i<size; i++) 
 buf[i] = SPACE; 
 } 
 // 顯示圖案 
 void drawAll(char* buf, int layerCount)   { 
 int rowLen = getRowLength(layerCount); 
 char* pbuf = buf; 
 for (int i=0; i<rowLen; i++) 
 { 
 for (int j=0; j<rowLen; j++) 
 printf("%c", *pbuf++); 
 printf("\n"); 
 } 
 } 
 // 畫橫線 
 void drawHLine(char* buf, int layerCount, int x1, int x2, int y)   { 
 int rowLen = getRowLength(layerCount); 
 for (int i = x1; i <= x2; i++) 
 buf[i + rowLen * y] = STAR; 
 } 
 // 畫豎線 
 void drawVLine(char* buf, int layerCount, int x, int y1, int y2)   { 
 int rowLen = getRowLength(layerCount); 
 for (int i = y1; i <= y2; i++) 
 buf[x + i * rowLen] = STAR; 
 } 
 // 畫中心十字 
 void drawCenter(char* buf, int layerCount)   { 
 //每行的字符數 
 int x, y, rowLen = getRowLength(layerCount); 
 x = rowLen / 2; //中心的座標 
 y = rowLen / 2; //中心的座標 
 drawHLine(buf, layerCount, x-2, x+2, y); 
 drawVLine(buf, layerCount, x, y-2, y+2); 
 } 
 // 畫第layer層 
 void drawLayer(char* buf, int layer, int layerCount)   { 
 int cx, cy, n, offset, rowLen = getRowLength(layerCount); 
 cx = rowLen / 2; 
 cy = rowLen / 2; 
 n = layer * 2; 
 offset = 2 + layer * 2; 
 drawVLine(buf, layerCount, cx - offset, cy - n, cy + n); 
 drawVLine(buf, layerCount, cx + offset, cy - n, cy + n); 
 drawHLine(buf, layerCount, cx - n, cx + n, cy - offset); 
 drawHLine(buf, layerCount, cx - n, cx + n, cy + offset); 
 drawVLine(buf, layerCount, cx - n, cy - offset, cy - offset + 2); 
 drawVLine(buf, layerCount, cx + n, cy - offset, cy - offset + 2); 
 drawVLine(buf, layerCount, cx - n, cy + offset - 2, cy + offset); 
 drawVLine(buf, layerCount, cx + n, cy + offset - 2, cy + offset); 
 drawHLine(buf, layerCount, cx - n - 2, cx - n, cy - n); 
 drawHLine(buf, layerCount, cx + n, cx + n + 2, cy - n); 
 drawHLine(buf, layerCount, cx - n - 2, cx - n, cy + n); 
 drawHLine(buf, layerCount, cx + n, cx + n + 2, cy + n); 
 } 
 // 返回n層須要的緩存區大小 
 int getBufferSize(int layerCount)   { 
 int rowLen = getRowLength(layerCount); 
 return rowLen * rowLen; 
 } 
 int main()   { 
 int layerCount; 
 while (scanf("%d", &layerCount) != EOF) // 讀層數 
 { 
 if (layerCount <= 0) 
 break; 
 char* buf = (char *)malloc(getBufferSize(layerCount)); // 申請緩存區 
 clearAll(buf, layerCount); // 圖案初始化 
 drawCenter(buf, layerCount); // 畫中心十字 
 drawLayer(buf, 1, layerCount); 
 for (int i=1; i<=layerCount; i++) // 畫全部層 
 { 
 drawLayer(buf, i, layerCount); 
 } 
 drawAll(buf, layerCount); // 顯示圖案 
 free(buf); 
 } 
 system("PAUSE"); 
 return 0; 
 } 

歷屆試題 帶分數

問題描述
100 能夠表示爲帶分數的形式:100 = 3 + 69258 / 714。

還能夠表示爲:100 = 82 + 3546 / 197。

注意特徵:帶分數中,數字1~9分別出現且只出現一次(不包含0)。

相似這樣的帶分數,100 有 11 種表示法。

輸入格式
從標準輸入讀入一個正整數N (N<1000*1000)

輸出格式
程序輸出該數字用數碼1~9不重複不遺漏地組成帶分數表示的所有種數。

注意:不要求輸出每一個表示,只統計有多少表示法!

樣例輸入1
100
樣例輸出1
11
樣例輸入2
105
樣例輸出2
6

#include <stdio.h> 
 #include <stdlib.h> 
 typedef struct Interval 
 { 
 int pre; 
 int rear; 
 int satisfy; 
 }Interval; 
 Interval interval[7][5]; 
 int count=0; 
 //初始化 
 void Init()   { 
 int i,j; 
 int value; 
 for(i=1;i<7;i++) 
 { 
 value=i; 
 for(j=1;j<5;j++) 
 { 
 interval[i][j].pre=value++; 
 interval[i][j].rear=value; 
 } 
 } 
 } 
 //數組初始化爲0 
 void InitZero(int *sign)   { 
 int i; 
 sign[0]=1; 
 for(i=1;i<10;i++) 
 { 
 sign[i]=0; 
 } 
 } 
 //將一個數的各個位上拆分,並在相應的位上賦值1 
 int Split(int *sign,int value)   { 
 int index; 
 while(value) 
 { 
 index=value%10; 
 if(sign[index]==0) sign[index]=1; 
 else return 1; 
 value/=10; 
 } 
 return 0; 
 } 
 //計算一個數的位數 
 int CountBit(int value)   { 
 int n=0; 
 while(value) 
 { 
 n++; 
 value/=10; 
 } 
 return n; 
 } 
 //將一個整型數組轉換成一個整數 
 int CreateInteger(int *data,int n)   { 
 int i; 
 int value=0; 
 for(i=0;i<n;i++) 
 { 
 value=value*10+data[i]; 
 } 
 return value; 
 } 
 //檢查是否每一個數都用到 
 int Check(int *sign)   { 
 int i; 
 for(i=1;i<10;i++) 
 { 
 if(sign[i]==0) return 0; 
 } 
 return 1; 
 } 
 //複製 
 void Copy(int *sign,int *temp_sign)   { 
 int i; 
 for(i=0;i<10;i++) 
 { 
 temp_sign[i]=sign[i]; 
 } 
 } 
 //建立一個n位數的整數 
 void CreateNBitNumber(int *sign,int *data,int n,int m,int value,int value3)   { 
 if(n==m) 
 { 
 int value1=CreateInteger(data,n); 
 int value2=value1*value; 
 int temp_sign[10]; 
 Copy(sign,temp_sign); 
 if(!Split(temp_sign,value2) && Check(temp_sign)) 
 { 
 count++; 
 } 
 } 
 else 
 { 
 int i; 
 for(i=1;i<10;i++) 
 { 
 if(sign[i]==0) 
 { 
 sign[i]=1; 
 data[m]=i; 
 CreateNBitNumber(sign,data,n,m+1,value,value3); 
 sign[i]=0; 
 } 
 } 
 } 
 } 
 //求出解 
 void Create(int value)   { 
 int i,j; 
 int sign[10]; 
 int result; 
 int result_n; 
 int n; 
 for(i=3;i<value;i++) 
 { 
 InitZero(sign); 
 if(Split(sign,i)) continue; 
 result=value-i; 
 result_n=CountBit(result); 
 n=CountBit(i); 
 for(j=1;j<5;j++) 
 { 
 if( ((interval[result_n][j].pre+j)==(9-n)) || ((interval[result_n][j].rear+j)==(9-n))) 
 { 
 int data[5]; 
 CreateNBitNumber(sign,data,j,0,result,i); 
 } 
 } 
 } 
 } 
 int main()   { 
 int value; 
 scanf("%d",&value); 
 Init(); 
 Create(value); 
 printf("%d\n",count); 
 return 0; 
 } 

歷屆試題 剪格子

問題描述
以下圖所示,3 x 3 的格子中填寫了一些整數。

+----+--+ |10 1|52|
+--***--+ |20|30 1|
*--+
| 1| 2| 3|
+--+--+--+
咱們沿着圖中的星號線剪開,獲得兩個部分,每一個部分的數字和都是60。

本題的要求就是請你編程斷定:對給定的m x n 的格子中的整數,是否能夠分割爲兩個部分,使得這兩個區域的數字和相等。

若是存在多種解答,請輸出包含左上角格子的那個區域包含的格子的最小數目。

若是沒法分割,則輸出 0。

輸入格式
程序先讀入兩個整數 m n 用空格分割 (m,n<10)。

表示表格的寬度和高度。

接下來是n行,每行m個正整數,用空格分開。每一個整數不大於10000。

輸出格式
輸出一個整數,表示在全部解中,包含左上角的分割區可能包含的最小的格子數目。
樣例輸入1
3 3
10 1 52
20 30 1
1 2 3
樣例輸出1
3
樣例輸入2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
樣例輸出2
10

#include <stdio.h> 
 #define N 10 
 int num[N][N]; 
 int tag[N][N] = {0}; 
 int m, n; 
 int r = 100; 
 int find(int i, int j, int t, int ntag[][N])   { 
 int count = 0; 
 if (i < 0 || i >= n || j < 0 || j >= m || ntag[i][j] == 1) 
 return 0; 
 ntag[i][j] = 1; 
 if (tag[i][j] != t) 
 return 0; 
 count++; 
 count += find(i - 1, j, t, ntag); 
 count += find(i + 1, j, t, ntag); 
 count += find(i, j - 1, t, ntag); 
 count += find(i, j + 1, t, ntag); 
 return count; 
 } 
 int isbad()   { 
 int i, j, k = 0,ge2; 
 int t = tag[0][0]; 
 int ntag1[N][N] = {0}; 
 int ntag2[N][N] = {0}; 
 int ge1 = find(0, 0, t, ntag1); 
 for (i = 0; i < n; i++) 
 { 
 for (j = 0; j < m; j++) 
 { 
 if (tag[i][j] != t) 
 { 
 k = 1; 
 break; 
 } 
 } 
 if (k == 1) 
 break; 
 } 
 if (i == n && j == m) 
 return 0; 
 ge2 = find(i, j, tag[i][j], ntag2); 
 return ge1 + ge2 != m * n; 
 } 
 int bad(int i, int j)   { 
 int b; 
 if (i < 0 || i >= n || j < 0 || j >= m || tag[i][j] == 1) 
 return 1; 
 tag[i][j] = 1; 
 b = isbad(); 
 tag[i][j] = 0; 
 return b; 
 } 
 void go(int i, int j, int k, int count)   { 
 if (bad(i, j) || count < num[i][j]) 
 return; 
 k++; 
 if (count == num[i][j]) 
 { 
 if (r > k) 
 r = k; 
 return; 
 } 
 tag[i][j] = 1; 
 count -= num[i][j]; 
 go(i - 1, j, k, count); 
 go(i + 1, j, k, count); 
 go(i, j - 1, k, count); 
 go(i, j + 1, k, count); 
 tag[i][j] = 0; 
 } 
 int main()   { 
 int i, j; 
 int half = 0; 
 scanf("%d %d", &m, &n); 
 for (i = 0; i < n; i++) 
 for (j = 0; j < m; j++) 
 { 
 scanf("%d", &num[i][j]); 
 half += num[i][j]; 
 } 
 if (half % 2 == 0 && half >= num[0][0] * 2) 
 { 
 half /= 2; 
 go(0, 0, 0, half); 
 } 
 if (r == 100) 
 r = 0; 
 printf("%d", r); 
 return 0; 
 } 

歷屆試題 錯誤票據

問題描述
某涉密單位下發了某種票據,並要在年終所有收回。

每張票據有惟一的ID號。整年全部票據的ID號是連續的,但ID的開始數碼是隨機選定的。

由於工做人員疏忽,在錄入ID號的時候發生了一處錯誤,形成了某個ID斷號,另一個ID重號。

你的任務是經過編程,找出斷號的ID和重號的ID。

假設斷號不可能發生在最大和最小號。

輸入格式
要求程序首先輸入一個整數N(N<100)表示後面數據行數。

接着讀入N行數據。

每行數據長度不等,是用空格分開的若干個(不大於100個)正整數(不大於100000),請注意行內和行末可能有多餘的空格,你的程序須要能處理這些空格。

每一個整數表明一個ID號。

輸出格式
要求程序輸出1行,含兩個整數m n,用空格分隔。

其中,m表示斷號ID,n表示重號ID

樣例輸入1
2
5 6 8 11 9
10 12 9
樣例輸出1
7 9
樣例輸入2
6
164 178 108 109 180 155 141 159 104 182 179 118 137 184 115 124 125 129 168 196
172 189 127 107 112 192 103 131 133 169 158
128 102 110 148 139 157 140 195 197
185 152 135 106 123 173 122 136 174 191 145 116 151 143 175 120 161 134 162 190
149 138 142 146 199 126 165 156 153 193 144 166 170 121 171 132 101 194 187 188
113 130 176 154 177 120 117 150 114 183 186 181 100 163 160 167 147 198 111 119
樣例輸出2
105 120

#include <stdio.h> 
 int main()   { 
 int a[10001]={0}; 
 long m,min=100000,max=0,i,n; 
 char c; 
 scanf("%d",&n); 
 for(i=0;i<n;i++) 
 while(1) 
 { 
 scanf("%ld",&m); 
 if(m>max) max=m; 
 if(m<min) min=m; 
 a[m]++; 
 c=getchar(); 
 if(c!=' ') break; 
 } 
 for(i=min;i<=max;i++) 
 { 
 if(a[i]==0) printf("%ld ",i); 
 if(a[i]==2) m=i; 
 } 
 printf("%ld",m); 
 return 0; 
 } 

歷屆試題 翻硬幣

問題描述
小明正在玩一個「翻硬幣」的遊戲。

桌上放着排成一排的若干硬幣。咱們用 * 表示正面,用 o 表示反面(是小寫字母,不是零)。

好比,可能情形是:oo*oooo

若是同時翻轉左邊的兩個硬幣,則變爲:oooo***oooo

如今小明的問題是:若是已知了初始狀態和要達到的目標狀態,每次只能同時翻轉相鄰的兩個硬幣,那麼對特定的局面,最少要翻動多少次呢?

咱們約定:把翻動相鄰的兩個硬幣叫作一步操做,那麼要求:

輸入格式
兩行等長的字符串,分別表示初始狀態和要達到的目標狀態。每行的長度<1000

輸出格式
一個整數,表示最小操做步數。

樣例輸入1


oo
樣例輸出1
5
樣例輸入2
*ooo
*ooo

樣例輸出2
1

//author :C博客用戶 qq_332040812 
 # include <stdio.h> 
 # include <stdlib.h> 
 # include <string.h> 
 char str1[1000]; 
 char str2[1000]; 
 int main(void)   { 
 int len = 0,i,t = 0,sum = 0,c = 0; 
 scanf("%s",str1); 
 scanf("%s",str2); 
 len = strlen(str1); 
 for(i = 0; i < len; ++i) 
 { 
 if( str1[i] != str2[i] ) 
 { 
 t = i - t; 
 ++c; 
 } 
 if(c == 2) 
 { 
 c = 0; 
 sum +=t; 
 t = 0; 
 } 
 } 
 printf("%d",sum); 
 return 0; 
 } 
 #include <stdio.h> 
 #include <string.h> 
 #define MaxSize 1005 
 void getResult(char *start,char *end)   { 
 int len=strlen(start); 
 int i; 
 int count=0; 
 int flag1[MaxSize]={0},flag2[MaxSize]={0}; 
 //printf("字符串長度%d\n",len); 
 //memset(flag1,1,sizeof(int)); 
 //memset(flag2,1,sizeof(int)); 
 // 
 for(i=0;i<len;i++) 
 { 
 if(start[i]=='o') 
 { 
 flag1[i]=1; 
 } 
 if(end[i]=='o') 
 { 
 flag2[i]=1; 
 } 
 } 
 for(i=0;i<len-1;i++) 
 { 
 if(flag1[i]!=flag2[i]) 
 { 
 flag1[i]=!flag1[i]; 
 flag1[i+1]=!flag1[i+1]; 
 count++; 
 } 
 } 
 if(flag1[len-1]!=flag2[len-1]) 
 { 
 count++; 
 } 
 printf("%d\n",count); 
 return ; 
 } 
 main() 
 { 
 char start[MaxSize],end[MaxSize]; 
 gets(start); 
 gets(end); 
 getResult(start,end); 
 return 0; 
 } 

歷屆試題 連號區間數

問題描述
小明這些天一直在思考這樣一個奇怪而有趣的問題:

在1~N的某個全排列中有多少個連號區間呢?這裏所說的連號區間的定義是:

若是區間[L, R] 裏的全部元素(即此排列的第L個到第R個元素)遞增排序後能獲得一個長度爲R-L+1的「連續」數列,則稱這個區間連號區間。

當N很小的時候,小明能夠很快地算出答案,可是當N變大的時候,問題就不是那麼簡單了,如今小明須要你的幫助。

輸入格式
第一行是一個正整數N (1 <= N <= 50000), 表示全排列的規模。

第二行是N個不一樣的數字Pi(1 <= Pi <= N), 表示這N個數字的某一全排列。

輸出格式
輸出一個整數,表示不一樣連號區間的數目。

樣例輸入1
4
3 2 4 1
樣例輸出1
7
樣例輸入2
5
3 4 2 5 1
樣例輸出2
9

#include<stdio.h> 
 int main()   { 
 int s[50005],a,i,min,max,count=0,j; 
 scanf("%d",&a); 
 for( i = 0; i < a; i++) { 
 scanf("%d",&s[i]); 
 } 
 for( i = 0; i <a;i++ ){ 
 min=s[i]; 
 max=s[i]; 
 for( j = i; j <a; j++) { 
 if(min>s[j]){min =s[j];} 
 if(max<s[j]){max =s[j];} 
 if((max-min)==(j-i)){ 
 count++; 
 } 
 } 
 } 
 printf("%d",count); 
 return 0; 
 } 

歷屆試題 買不到的數目

問題描述
小明開了一家糖果店。他別出心裁:把水果糖包成4顆一包和7顆一包的兩種。糖

果不能拆包賣。

小朋友來買糖的時候,他就用這兩種包裝來組合。固然有些糖果數目是沒法組合

出來的,好比要買 10 顆糖。

你能夠用計算機測試一下,在這種包裝狀況下,最大不能買到的數量是17。大於

17的任何數字均可以用4和7組合出來。

本題的要求就是在已知兩個包裝的數量時,求最大不能組合出的數字。

輸入格式
兩個正整數,表示每種包裝中糖的顆數(都很少於1000)

輸出格式
一個正整數,表示最大不能買到的糖數

樣例輸入1
4 7
樣例輸出1
17
樣例輸入2
3 5
樣例輸出2
7

a*b-a-b證實過程?百度

#include <stdio.h> 
 main() 
 { 
 int a,b; 
 scanf("%d%d",&a,&b); 
 printf("%d\n",a*b-a-b); 
 return 0; 
 } 

歷屆試題 大臣的旅費

問題描述
好久之前,T王國空前繁榮。爲了更好地管理國家,王國修建了大量的快速路,用於鏈接首都和王國內的各大城市。

爲節省經費,T國的大臣們通過思考,制定了一套優秀的修建方案,使得任何一個大城市都能從首都直接或者經過其餘大城市間接到達。同時,若是不重複通過大城市,從首都到達每一個大城市的方案都是惟一的。

J是T國重要大臣,他巡查於各大城市之間,體察民情。因此,從一個城市快馬加鞭地到另外一個城市成了J最常作的事情。他有一個錢袋,用於存放往來城市間的路費。

聰明的J發現,若是不在某個城市停下來修整,在連續行進過程當中,他所花的路費與他已走過的距離有關,在走第x公里到第x+1公里這一公里中(x是整數),他花費的路費是x+10這麼多。也就是說走1公里花費11,走2公里要花費23。

J大臣想知道:他從某一個城市出發,中間不休息,到達另外一個城市,全部可能花費的路費中最可能是多少呢?

輸入格式
輸入的第一行包含一個整數n,表示包括首都在內的T王國的城市數

城市從1開始依次編號,1號城市爲首都。

接下來n-1行,描述T國的高速路(T國的高速路必定是n-1條)

每行三個整數Pi, Qi, Di,表示城市Pi和城市Qi之間有一條高速路,長度爲Di公里。

輸出格式
輸出一個整數,表示大臣J最多花費的路費是多少。

樣例輸入1
5
1 2 2
1 3 1
2 4 5
2 5 4
樣例輸出1
135
輸出格式
大臣J從城市4到城市5要花費135的路費。

#include <stdio.h> 
 #include <string.h> 
 #include <math.h> 
 #include <stdlib.h> 
 struct node; 
 typedef struct node Node; 
 typedef Node *PtrToNode; 
 typedef PtrToNode List; 
 typedef PtrToNode Position; 
 struct node   { 
 int n; 
 int val; 
 Position next; 
 }; 
 int count=0; 
 int max=0; 
 int x; 
 int *visit; //是否已遍歷 
 Position Last(List l); //找出最後項 
 void Insert(int x,int q,List l,Position p); //在p後插入含x的項 
 void Dfs(int a,List l[]); //深度優先搜索 
 int Num(List l); 
 int main(void)   { 
 int n,u,v,q,a,b; 
 int i,j,k; 
 Node *head; 
 List *l,tmp; 
 Position p; 
 fscanf(stdin,"%d",&n); 
 head=(Node *)malloc(sizeof(Node)*(n+1)); 
 l=(List *)malloc(sizeof(List)*(n+1)); 
 visit=(int *)malloc(sizeof(int)*(n+1)); 
 for(i=0;i<=n;i++) //初始化表頭及鏈表 
 { 
 head[i].next=NULL; 
 l[i]=&head[i]; 
 } 
 for(i=1;i<=n-1;i++) //創建無向圖 
 { 
 fscanf(stdin,"%d%d%d",&u,&v,&q); 
 Insert(v,q,l[u],Last(l[u])); 
 Insert(u,q,l[v],Last(l[v])); 
 } 
 for(j=1;j<=n;j++) 
 visit[j]=0; 
 Dfs(1,l); //第一次遍歷,找到點a,用全局變量x保存 
 for(j=1;j<=n;j++) 
 visit[j]=0; 
 count=0; 
 max=0; 
 Dfs(x,l); //第二次遍歷,找到點b,用全局變量x保存,此時max爲最大距離 
 printf("%d",max*10+(max+1)*max/2); 
 return 0; 
 } 
 Position Last(List l)   { 
 Position p; 
 for(p=l;p->next!=NULL;p=p->next); 
 return p; 
 } 
 void Insert(int x,int q,List l,Position p)   { 
 Position tmp; 
 tmp=(Position) malloc(sizeof(Node)); 
 tmp->n=x; 
 tmp->val=q; 
 tmp->next=p->next; 
 p->next=tmp; 
 } 
 void Dfs(int a,List l[])   { 
 Position p; 
 visit[a]=1; 
 for(p=l[a]->next;p!=NULL;p=p->next) 
 if(!(visit[p->n])) 
 { 
 count+=p->val; 
 if(count>max) 
 { 
 max=count; 
 x=p->n; 
 } 
 Dfs(p->n,l); 
 count-=p->val; 
 } 
 } 
 int Num(List l)   { 
 int n=0; 
 Position p; 
 for(p=l->next;p!=NULL;p=p->next) 
 n++; 
 return n; 
 } 

歷屆試題 幸運數

問題描述
幸運數是波蘭數學家烏拉姆命名的。它採用與生成素數相似的「篩法」生成


首先從1開始寫出天然數1,2,3,4,5,6,….

1 就是第一個幸運數。

咱們從2這個數開始。把全部序號能被2整除的項刪除,變爲:

1 _ 3 _ 5 _ 7 _ 9 ….

把它們縮緊,從新記序,爲:

1 3 5 7 9 …. 。這時,3爲第2個幸運數,而後把全部能被3整除的序號位置的數刪去。注意,是序號位置,不是那個數自己可否被3整除!! 刪除的應該是5,11, 17, …

此時7爲第3個幸運數,而後再刪去序號位置能被7整除的(19,39,…)

最後剩下的序列相似:

1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, …

輸入格式
輸入兩個正整數m n, 用空格分開 (m < n < 1000*1000)
輸出格式
程序輸出 位於m和n之間的幸運數的個數(不包含m和n)。
樣例輸入1
1 20
樣例輸出1
5
樣例輸入2
30 69
樣例輸出2
8

#include<stdio.h> 
 #define MAXN 1000010 
 int flag[MAXN]; 
 int m,n,a[MAXN],s[MAXN],size=0; 
 int fa(int k)   { 
 if(flag[k]) 
 return a[k]; 
 return fa(k-1); 
 } 
 int main()   { 
 int i, p, k, j; 
 scanf("%d%d",&m,&n); 
 for(i=1;i<=n;i+=2) 
 { 
 s[++size]=i; 
 flag[i]=1; 
 a[i]=size; 
 } 
 for(i=2;i<=size;i++) 
 { 
 int Mod=s[i],d=s[i]-1; 
 if(Mod>size) 
 break; 
 for(p=1,j=Mod;j<=size;j+=Mod,p++) 
 { 
 flag[s[j]]=0; 
 for(k=1;k<Mod&&k+j<=size;k++) 
 { 
 s[++d]=s[j+k]; 
 a[s[j+k]]-=p; 
 } 
 } 
 size=d; 
 } 
 printf("%d\n",fa(n-1)-fa(m)); 
 return 0; 
 } 

歷屆試題 橫向打印二叉樹

問題描述
二叉樹能夠用於排序。其原理很簡單:對於一個排序二叉樹添加新節點時,先與根節點比較,若小則交給左子樹繼續處理,不然交給右子樹。

當遇到空子樹時,則把該節點放入那個位置。

好比,10 8 5 7 12 4 的輸入順序,應該建成二叉樹以下圖所示,其中.表示空白。

…|-12
10-|
…|-8-|
…….|…|-7
…….|-5-|
………..|-4
本題目要求:根據已知的數字,創建排序二叉樹,並在標準輸出中橫向打印該二叉樹。

輸入格式
輸入數據爲一行空格分開的N個整數。 N<100,每一個數字不超過10000。

輸入數據中沒有重複的數字。

輸出格式
輸出該排序二叉樹的橫向表示。爲了便於評卷程序比對空格的數目,請把空格用句點代替:

樣例輸入1
10 5 20
樣例輸出1
…|-20
10-|
…|-5
樣例輸入2
5 10 20 8 4 7
樣例輸出2
…….|-20
..|-10-|
..|….|-8-|
..|……..|-7
5-|
..|-4

#include<stdio.h> 
 #include<stdlib.h> 
 #include<string.h> 
 typedef struct TNode   { 
 int key; 
 struct TNode *left; 
 struct TNode *right; 
 }TNode, *Tree; 
 Tree insert(Tree root, Tree src)   { 
 if(root == NULL) 
 { 
 root = src; 
 } 
 else if(src->key > root->key) 
 { 
 root->left = insert(root->left, src); 
 } 
 else 
 { 
 root->right = insert(root->right, src); 
相關文章
相關標籤/搜索