藍橋杯習題html
藍橋杯練習系統習題加答案更新新地址(已更新200左右習題)node
http://blog.csdn.net/rodestillfaraway ios
目錄算法
算法訓練(詳見 算法-藍橋杯習題(一))Go編程
算法訓練(詳見 算法-藍橋杯習題(二))Go數組
算法提升(waiting...)緩存
歷屆試題(詳見 算法-藍橋杯習題(六))Go安全
歷屆試題(詳見 算法-藍橋杯習題(七))Go網絡
藍橋杯練習系統評測數據測試
連接:
http://pan.baidu.com/s/1mhophTQ
密碼: m2pa
歷屆試題(PartA-10題)
1 /* 2 歷屆試題 核桃的數量 3 4 問題描述 5 小張是軟件項目經理,他帶領3個開發組。工期緊,今天都在加班呢。爲鼓舞士氣,小張打算給每一個組發一袋核桃(據傳言能補腦)。他的要求是: 6 7 1. 各組的核桃數量必須相同 8 9 2. 各組內必須能平分核桃(固然是不能打碎的) 10 11 3. 儘可能提供知足1,2條件的最小數量(節約鬧革命嘛) 12 13 輸入格式 14 輸入包含三個正整數a, b, c,表示每一個組正在加班的人數,用空格分開(a,b,c<30) 15 輸出格式 16 輸出一個正整數,表示每袋核桃的數量。 17 樣例輸入1 18 2 4 5 19 樣例輸出1 20 20 21 樣例輸入2 22 3 1 1 23 樣例輸出2 24 3 25 */ 26 #include <stdio.h> 27 main() 28 { 29 int a,b,c,s; 30 do 31 { 32 scanf("%d%d%d", &a,&b,&c); 33 } 34 while(a>30&&b>30&&c>30); 35 s=f1(a,b); 36 // printf("%d\n",s); 37 s=f1(s,c); 38 printf("%d\n",s); 39 return 0; 40 } 41 42 int f1(int a,int b) 43 { 44 int t,m; 45 int c; 46 if (a < b) 47 { 48 t = a; 49 a = b; 50 b = t; 51 } 52 m = a * b; 53 54 55 c = a % b; 56 while (c != 0) 57 { 58 a = b; 59 b = c; 60 c = a % b; 61 } 62 63 return m/b; 64 }
1 /* 2 歷屆試題 打印十字圖 3 4 問題描述 5 小明爲某機構設計了一個十字型的徽標(並不是紅十字會啊),以下所示: 6 7 ..$$$$$$$$$$$$$.. 8 ..$...........$.. 9 $$$.$$$$$$$$$.$$$ 10 $...$.......$...$ 11 $.$$$.$$$$$.$$$.$ 12 $.$...$...$...$.$ 13 $.$.$$$.$.$$$.$.$ 14 $.$.$...$...$.$.$ 15 $.$.$.$$$$$.$.$.$ 16 $.$.$...$...$.$.$ 17 $.$.$$$.$.$$$.$.$ 18 $.$...$...$...$.$ 19 $.$$$.$$$$$.$$$.$ 20 $...$.......$...$ 21 $$$.$$$$$$$$$.$$$ 22 ..$...........$.. 23 ..$$$$$$$$$$$$$.. 24 對方同時也須要在電腦dos窗口中以字符的形式輸出該標誌,並能任意控制層數。 25 26 輸入格式 27 一個正整數 n (n<30) 表示要求打印圖形的層數。 28 輸出格式 29 對應包圍層數的該標誌。 30 樣例輸入1 31 1 32 樣例輸出1 33 ..$$$$$.. 34 ..$...$.. 35 $$$.$.$$$ 36 $...$...$ 37 $.$$$$$.$ 38 $...$...$ 39 $$$.$.$$$ 40 ..$...$.. 41 ..$$$$$.. 42 樣例輸入2 43 3 44 樣例輸出2 45 ..$$$$$$$$$$$$$.. 46 ..$...........$.. 47 $$$.$$$$$$$$$.$$$ 48 $...$.......$...$ 49 $.$$$.$$$$$.$$$.$ 50 $.$...$...$...$.$ 51 $.$.$$$.$.$$$.$.$ 52 $.$.$...$...$.$.$ 53 $.$.$.$$$$$.$.$.$ 54 $.$.$...$...$.$.$ 55 $.$.$$$.$.$$$.$.$ 56 $.$...$...$...$.$ 57 $.$$$.$$$$$.$$$.$ 58 $...$.......$...$ 59 $$$.$$$$$$$$$.$$$ 60 ..$...........$.. 61 ..$$$$$$$$$$$$$.. 62 提示 63 請仔細觀察樣例,尤爲要注意句點的數量和輸出位置。 64 */ 65 #include <cstdlib> 66 #include <iostream> 67 68 #include <stdio.h> 69 70 #include <stdlib.h> 71 72 using namespace std; 73 74 75 const 76 77 int SPACE = '.'; 78 79 int STAR = '$'; 80 81 82 // 獲取每行的字符數 83 84 int getRowLength(int layerCount) 85 { 86 87 return 5 + layerCount * 4; 88 89 } 90 91 92 93 // 初始化 94 95 void clearAll(char* buf, int layerCount) 96 97 { 98 99 int size = getRowLength(layerCount); 100 101 size = size * size; 102 103 for (int i=0; i<size; i++) 104 105 buf[i] = SPACE; 106 107 } 108 109 110 111 // 顯示圖案 112 113 void drawAll(char* buf, int layerCount) 114 115 { 116 117 int rowLen = getRowLength(layerCount); 118 119 char* pbuf = buf; 120 121 for (int i=0; i<rowLen; i++) 122 123 { 124 125 for (int j=0; j<rowLen; j++) 126 127 printf("%c", *pbuf++); 128 129 printf("\n"); 130 131 } 132 133 } 134 135 136 137 // 畫橫線 138 139 void drawHLine(char* buf, int layerCount, int x1, int x2, int y) 140 { 141 142 int rowLen = getRowLength(layerCount); 143 144 for (int i = x1; i <= x2; i++) 145 146 buf[i + rowLen * y] = STAR; 147 148 } 149 150 151 152 // 畫豎線 153 154 void drawVLine(char* buf, int layerCount, int x, int y1, int y2) 155 156 { 157 158 int rowLen = getRowLength(layerCount); 159 160 for (int i = y1; i <= y2; i++) 161 162 buf[x + i * rowLen] = STAR; 163 164 } 165 166 167 168 // 畫中心十字 169 170 void drawCenter(char* buf, int layerCount) 171 { 172 //每行的字符數 173 int x, y, rowLen = getRowLength(layerCount); 174 175 x = rowLen / 2; //中心的座標 176 177 y = rowLen / 2; //中心的座標 178 179 drawHLine(buf, layerCount, x-2, x+2, y); 180 181 drawVLine(buf, layerCount, x, y-2, y+2); 182 183 } 184 185 186 187 // 畫第layer層 188 189 void drawLayer(char* buf, int layer, int layerCount) 190 191 { 192 193 int cx, cy, n, offset, rowLen = getRowLength(layerCount); 194 195 cx = rowLen / 2; 196 197 cy = rowLen / 2; 198 199 n = layer * 2; 200 201 offset = 2 + layer * 2; 202 203 drawVLine(buf, layerCount, cx - offset, cy - n, cy + n); 204 205 drawVLine(buf, layerCount, cx + offset, cy - n, cy + n); 206 207 drawHLine(buf, layerCount, cx - n, cx + n, cy - offset); 208 209 drawHLine(buf, layerCount, cx - n, cx + n, cy + offset); 210 211 drawVLine(buf, layerCount, cx - n, cy - offset, cy - offset + 2); 212 213 drawVLine(buf, layerCount, cx + n, cy - offset, cy - offset + 2); 214 215 drawVLine(buf, layerCount, cx - n, cy + offset - 2, cy + offset); 216 217 drawVLine(buf, layerCount, cx + n, cy + offset - 2, cy + offset); 218 219 drawHLine(buf, layerCount, cx - n - 2, cx - n, cy - n); 220 221 drawHLine(buf, layerCount, cx + n, cx + n + 2, cy - n); 222 223 drawHLine(buf, layerCount, cx - n - 2, cx - n, cy + n); 224 225 drawHLine(buf, layerCount, cx + n, cx + n + 2, cy + n); 226 227 } 228 229 230 231 // 返回n層須要的緩存區大小 232 233 int getBufferSize(int layerCount) 234 235 { 236 237 int rowLen = getRowLength(layerCount); 238 239 return rowLen * rowLen; 240 241 } 242 243 244 245 int main() 246 { 247 248 int layerCount; 249 while (scanf("%d", &layerCount) != EOF) // 讀層數 250 { 251 if (layerCount <= 0) 252 break; 253 254 char* buf = (char *)malloc(getBufferSize(layerCount)); // 申請緩存區 255 256 clearAll(buf, layerCount); // 圖案初始化 257 258 drawCenter(buf, layerCount); // 畫中心十字 259 drawLayer(buf, 1, layerCount); 260 261 for (int i=1; i<=layerCount; i++) // 畫全部層 262 { 263 drawLayer(buf, i, layerCount); 264 } 265 266 drawAll(buf, layerCount); // 顯示圖案 267 268 free(buf); 269 270 } 271 system("PAUSE"); 272 273 return 0; 274 275 }
1 /* 2 歷屆試題 帶分數 3 4 問題描述 5 100 能夠表示爲帶分數的形式:100 = 3 + 69258 / 714。 6 7 還能夠表示爲:100 = 82 + 3546 / 197。 8 9 注意特徵:帶分數中,數字1~9分別出現且只出現一次(不包含0)。 10 11 相似這樣的帶分數,100 有 11 種表示法。 12 13 輸入格式 14 從標準輸入讀入一個正整數N (N<1000*1000) 15 16 輸出格式 17 程序輸出該數字用數碼1~9不重複不遺漏地組成帶分數表示的所有種數。 18 19 注意:不要求輸出每一個表示,只統計有多少表示法! 20 21 樣例輸入1 22 100 23 樣例輸出1 24 11 25 樣例輸入2 26 105 27 樣例輸出2 28 6 29 */ 30 #include <stdio.h> 31 #include <stdlib.h> 32 33 typedef struct Interval 34 { 35 int pre; 36 int rear; 37 int satisfy; 38 }Interval; 39 Interval interval[7][5]; 40 int count=0; 41 42 //初始化 43 void Init() 44 { 45 int i,j; 46 int value; 47 for(i=1;i<7;i++) 48 { 49 value=i; 50 for(j=1;j<5;j++) 51 { 52 interval[i][j].pre=value++; 53 interval[i][j].rear=value; 54 } 55 } 56 } 57 58 //數組初始化爲0 59 void InitZero(int *sign) 60 { 61 int i; 62 sign[0]=1; 63 for(i=1;i<10;i++) 64 { 65 sign[i]=0; 66 } 67 } 68 69 //將一個數的各個位上拆分,並在相應的位上賦值1 70 int Split(int *sign,int value) 71 { 72 int index; 73 while(value) 74 { 75 index=value%10; 76 if(sign[index]==0) sign[index]=1; 77 else return 1; 78 value/=10; 79 } 80 return 0; 81 } 82 83 //計算一個數的位數 84 int CountBit(int value) 85 { 86 int n=0; 87 while(value) 88 { 89 n++; 90 value/=10; 91 } 92 return n; 93 } 94 95 //將一個整型數組轉換成一個整數 96 int CreateInteger(int *data,int n) 97 { 98 int i; 99 int value=0; 100 for(i=0;i<n;i++) 101 { 102 value=value*10+data[i]; 103 } 104 return value; 105 } 106 107 //檢查是否每一個數都用到 108 int Check(int *sign) 109 { 110 int i; 111 for(i=1;i<10;i++) 112 { 113 if(sign[i]==0) return 0; 114 } 115 return 1; 116 } 117 118 //複製 119 void Copy(int *sign,int *temp_sign) 120 { 121 int i; 122 for(i=0;i<10;i++) 123 { 124 temp_sign[i]=sign[i]; 125 } 126 } 127 //建立一個n位數的整數 128 void CreateNBitNumber(int *sign,int *data,int n,int m,int value,int value3) 129 { 130 if(n==m) 131 { 132 int value1=CreateInteger(data,n); 133 int value2=value1*value; 134 int temp_sign[10]; 135 Copy(sign,temp_sign); 136 if(!Split(temp_sign,value2) && Check(temp_sign)) 137 { 138 count++; 139 } 140 } 141 else 142 { 143 int i; 144 for(i=1;i<10;i++) 145 { 146 if(sign[i]==0) 147 { 148 sign[i]=1; 149 data[m]=i; 150 CreateNBitNumber(sign,data,n,m+1,value,value3); 151 sign[i]=0; 152 } 153 } 154 } 155 } 156 157 //求出解 158 void Create(int value) 159 { 160 int i,j; 161 int sign[10]; 162 int result; 163 int result_n; 164 int n; 165 for(i=3;i<value;i++) 166 { 167 InitZero(sign); 168 if(Split(sign,i)) continue; 169 result=value-i; 170 result_n=CountBit(result); 171 n=CountBit(i); 172 for(j=1;j<5;j++) 173 { 174 if( ((interval[result_n][j].pre+j)==(9-n)) || ((interval[result_n][j].rear+j)==(9-n))) 175 { 176 int data[5]; 177 CreateNBitNumber(sign,data,j,0,result,i); 178 } 179 } 180 } 181 } 182 183 int main() 184 { 185 int value; 186 scanf("%d",&value); 187 Init(); 188 Create(value); 189 printf("%d\n",count); 190 return 0; 191 }
1 /* 2 歷屆試題 剪格子 3 4 問題描述 5 以下圖所示,3 x 3 的格子中填寫了一些整數。 6 7 +--*--+--+ 8 |10* 1|52| 9 +--****--+ 10 |20|30* 1| 11 *******--+ 12 | 1| 2| 3| 13 +--+--+--+ 14 咱們沿着圖中的星號線剪開,獲得兩個部分,每一個部分的數字和都是60。 15 16 本題的要求就是請你編程斷定:對給定的m x n 的格子中的整數,是否能夠分割爲兩個部分,使得這兩個區域的數字和相等。 17 18 若是存在多種解答,請輸出包含左上角格子的那個區域包含的格子的最小數目。 19 20 若是沒法分割,則輸出 0。 21 22 輸入格式 23 程序先讀入兩個整數 m n 用空格分割 (m,n<10)。 24 25 表示表格的寬度和高度。 26 27 接下來是n行,每行m個正整數,用空格分開。每一個整數不大於10000。 28 29 輸出格式 30 輸出一個整數,表示在全部解中,包含左上角的分割區可能包含的最小的格子數目。 31 樣例輸入1 32 3 3 33 10 1 52 34 20 30 1 35 1 2 3 36 樣例輸出1 37 3 38 樣例輸入2 39 4 3 40 1 1 1 1 41 1 30 80 2 42 1 1 1 100 43 樣例輸出2 44 10 45 */ 46 #include <stdio.h> 47 #define N 10 48 int num[N][N]; 49 int tag[N][N] = {0}; 50 int m, n; 51 int r = 100; 52 int find(int i, int j, int t, int ntag[][N]) 53 { 54 int count = 0; 55 if (i < 0 || i >= n || j < 0 || j >= m || ntag[i][j] == 1) 56 return 0; 57 ntag[i][j] = 1; 58 if (tag[i][j] != t) 59 return 0; 60 count++; 61 count += find(i - 1, j, t, ntag); 62 count += find(i + 1, j, t, ntag); 63 count += find(i, j - 1, t, ntag); 64 count += find(i, j + 1, t, ntag); 65 return count; 66 } 67 68 int isbad() 69 { 70 int i, j, k = 0,ge2; 71 int t = tag[0][0]; 72 int ntag1[N][N] = {0}; 73 int ntag2[N][N] = {0}; 74 int ge1 = find(0, 0, t, ntag1); 75 for (i = 0; i < n; i++) 76 { 77 for (j = 0; j < m; j++) 78 { 79 if (tag[i][j] != t) 80 { 81 k = 1; 82 break; 83 } 84 } 85 if (k == 1) 86 break; 87 } 88 89 if (i == n && j == m) 90 return 0; 91 ge2 = find(i, j, tag[i][j], ntag2); 92 93 return ge1 + ge2 != m * n; 94 } 95 int bad(int i, int j) 96 { 97 int b; 98 if (i < 0 || i >= n || j < 0 || j >= m || tag[i][j] == 1) 99 return 1; 100 101 tag[i][j] = 1; 102 b = isbad(); 103 tag[i][j] = 0; 104 return b; 105 } 106 107 void go(int i, int j, int k, int count) 108 { 109 110 if (bad(i, j) || count < num[i][j]) 111 return; 112 k++; 113 114 if (count == num[i][j]) 115 { 116 if (r > k) 117 r = k; 118 return; 119 } 120 121 122 tag[i][j] = 1; 123 count -= num[i][j]; 124 go(i - 1, j, k, count); 125 go(i + 1, j, k, count); 126 go(i, j - 1, k, count); 127 go(i, j + 1, k, count); 128 tag[i][j] = 0; 129 } 130 131 int main() 132 { 133 134 int i, j; 135 int half = 0; 136 scanf("%d %d", &m, &n); 137 for (i = 0; i < n; i++) 138 for (j = 0; j < m; j++) 139 { 140 scanf("%d", &num[i][j]); 141 142 half += num[i][j]; 143 } 144 145 146 if (half % 2 == 0 && half >= num[0][0] * 2) 147 { 148 149 half /= 2; 150 go(0, 0, 0, half); 151 } 152 153 if (r == 100) 154 r = 0; 155 156 printf("%d", r); 157 158 return 0; 159 }
1 /* 2 歷屆試題 錯誤票據 3 4 問題描述 5 某涉密單位下發了某種票據,並要在年終所有收回。 6 7 每張票據有惟一的ID號。整年全部票據的ID號是連續的,但ID的開始數碼是隨機選定的。 8 9 由於工做人員疏忽,在錄入ID號的時候發生了一處錯誤,形成了某個ID斷號,另一個ID重號。 10 11 你的任務是經過編程,找出斷號的ID和重號的ID。 12 13 假設斷號不可能發生在最大和最小號。 14 15 輸入格式 16 要求程序首先輸入一個整數N(N<100)表示後面數據行數。 17 18 接着讀入N行數據。 19 20 每行數據長度不等,是用空格分開的若干個(不大於100個)正整數(不大於100000),請注意行內和行末可能有多餘的空格,你的程序須要能處理這些空格。 21 22 每一個整數表明一個ID號。 23 24 輸出格式 25 要求程序輸出1行,含兩個整數m n,用空格分隔。 26 27 其中,m表示斷號ID,n表示重號ID 28 29 樣例輸入1 30 2 31 5 6 8 11 9 32 10 12 9 33 樣例輸出1 34 7 9 35 樣例輸入2 36 6 37 164 178 108 109 180 155 141 159 104 182 179 118 137 184 115 124 125 129 168 196 38 172 189 127 107 112 192 103 131 133 169 158 39 128 102 110 148 139 157 140 195 197 40 185 152 135 106 123 173 122 136 174 191 145 116 151 143 175 120 161 134 162 190 41 149 138 142 146 199 126 165 156 153 193 144 166 170 121 171 132 101 194 187 188 42 113 130 176 154 177 120 117 150 114 183 186 181 100 163 160 167 147 198 111 119 43 樣例輸出2 44 105 120 45 */ 46 #include <stdio.h> 47 int main() 48 { 49 int a[10001]={0}; 50 long m,min=100000,max=0,i,n; 51 char c; 52 scanf("%d",&n); 53 for(i=0;i<n;i++) 54 while(1) 55 { 56 scanf("%ld",&m); 57 if(m>max) max=m; 58 if(m<min) min=m; 59 a[m]++; 60 c=getchar(); 61 if(c!=' ') break; 62 } 63 64 for(i=min;i<=max;i++) 65 { 66 if(a[i]==0) printf("%ld ",i); 67 if(a[i]==2) m=i; 68 } 69 printf("%ld",m); 70 71 return 0; 72 }
1 /* 2 歷屆試題 翻硬幣 3 4 問題描述 5 小明正在玩一個「翻硬幣」的遊戲。 6 7 桌上放着排成一排的若干硬幣。咱們用 * 表示正面,用 o 表示反面(是小寫字母,不是零)。 8 9 好比,可能情形是:**oo***oooo 10 11 若是同時翻轉左邊的兩個硬幣,則變爲:oooo***oooo 12 13 如今小明的問題是:若是已知了初始狀態和要達到的目標狀態,每次只能同時翻轉相鄰的兩個硬幣,那麼對特定的局面,最少要翻動多少次呢? 14 15 咱們約定:把翻動相鄰的兩個硬幣叫作一步操做,那麼要求: 16 17 輸入格式 18 兩行等長的字符串,分別表示初始狀態和要達到的目標狀態。每行的長度<1000 19 20 輸出格式 21 一個整數,表示最小操做步數。 22 23 樣例輸入1 24 ********** 25 o****o**** 26 樣例輸出1 27 5 28 樣例輸入2 29 *o**o***o*** 30 *o***o**o*** 31 樣例輸出2 32 1 33 */ 34 #include <stdio.h> 35 #include <string.h> 36 #define MaxSize 1005 37 38 void getResult(char *start,char *end) 39 { 40 int len=strlen(start); 41 int i; 42 int count=0; 43 int flag1[MaxSize]={0},flag2[MaxSize]={0}; 44 45 //printf("字符串長度%d\n",len); 46 47 //memset(flag1,1,sizeof(int)); 48 //memset(flag2,1,sizeof(int)); 49 50 // 51 /* 52 for(i=0;i<len;i++) 53 printf("%d ",flag1[i]); 54 printf("\n"); 55 return ; 56 */ 57 for(i=0;i<len;i++) 58 { 59 if(start[i]=='o') 60 { 61 flag1[i]=1; 62 } 63 if(end[i]=='o') 64 { 65 flag2[i]=1; 66 } 67 } 68 69 for(i=0;i<len-1;i++) 70 { 71 if(flag1[i]!=flag2[i]) 72 { 73 flag1[i]=!flag1[i]; 74 flag1[i+1]=!flag1[i+1]; 75 count++; 76 } 77 } 78 if(flag1[len-1]!=flag2[len-1]) 79 { 80 count++; 81 } 82 /* 83 for(i=0;i<len;i++) 84 printf("%d",flag1[i]); 85 printf("\n"); 86 */ 87 printf("%d\n",count); 88 89 return ; 90 } 91 92 main() 93 { 94 char start[MaxSize],end[MaxSize]; 95 96 gets(start); 97 gets(end); 98 99 getResult(start,end); 100 101 return 0; 102 }
1 /* 2 歷屆試題 連號區間數 3 4 問題描述 5 小明這些天一直在思考這樣一個奇怪而有趣的問題: 6 7 在1~N的某個全排列中有多少個連號區間呢?這裏所說的連號區間的定義是: 8 9 若是區間[L, R] 裏的全部元素(即此排列的第L個到第R個元素)遞增排序後能獲得一個長度爲R-L+1的「連續」數列,則稱這個區間連號區間。 10 11 當N很小的時候,小明能夠很快地算出答案,可是當N變大的時候,問題就不是那麼簡單了,如今小明須要你的幫助。 12 13 輸入格式 14 第一行是一個正整數N (1 <= N <= 50000), 表示全排列的規模。 15 16 第二行是N個不一樣的數字Pi(1 <= Pi <= N), 表示這N個數字的某一全排列。 17 18 輸出格式 19 輸出一個整數,表示不一樣連號區間的數目。 20 21 樣例輸入1 22 4 23 3 2 4 1 24 樣例輸出1 25 7 26 樣例輸入2 27 5 28 3 4 2 5 1 29 樣例輸出2 30 9 31 */ 32 #include<stdio.h> 33 int main() 34 { 35 int s[50005],a,i,min,max,count=0,j; 36 scanf("%d",&a); 37 for( i = 0; i < a; i++) { 38 scanf("%d",&s[i]); 39 } 40 for( i = 0; i <a;i++ ){ 41 min=s[i]; 42 max=s[i]; 43 for( j = i; j <a; j++) { 44 if(min>s[j]){min =s[j];} 45 if(max<s[j]){max =s[j];} 46 if((max-min)==(j-i)){ 47 count++; 48 } 49 50 } 51 } 52 printf("%d",count); 53 return 0; 54 }
1 /* 2 歷屆試題 買不到的數目 3 4 問題描述 5 小明開了一家糖果店。他別出心裁:把水果糖包成4顆一包和7顆一包的兩種。糖 6 7 果不能拆包賣。 8 9 小朋友來買糖的時候,他就用這兩種包裝來組合。固然有些糖果數目是沒法組合 10 11 出來的,好比要買 10 顆糖。 12 13 你能夠用計算機測試一下,在這種包裝狀況下,最大不能買到的數量是17。大於 14 15 17的任何數字均可以用4和7組合出來。 16 17 本題的要求就是在已知兩個包裝的數量時,求最大不能組合出的數字。 18 19 輸入格式 20 兩個正整數,表示每種包裝中糖的顆數(都很少於1000) 21 22 輸出格式 23 一個正整數,表示最大不能買到的糖數 24 25 樣例輸入1 26 4 7 27 樣例輸出1 28 17 29 樣例輸入2 30 3 5 31 樣例輸出2 32 7 33 34 a*b-a-b證實過程?百度 35 */ 36 #include <stdio.h> 37 38 main() 39 { 40 int a,b; 41 42 scanf("%d%d",&a,&b); 43 printf("%d\n",a*b-a-b); 44 45 return 0; 46 }
1 /* 2 歷屆試題 大臣的旅費 3 4 問題描述 5 好久之前,T王國空前繁榮。爲了更好地管理國家,王國修建了大量的快速路,用於鏈接首都和王國內的各大城市。 6 7 爲節省經費,T國的大臣們通過思考,制定了一套優秀的修建方案,使得任何一個大城市都能從首都直接或者經過其餘大城市間接到達。同時,若是不重複通過大城市,從首都到達每一個大城市的方案都是惟一的。 8 9 J是T國重要大臣,他巡查於各大城市之間,體察民情。因此,從一個城市快馬加鞭地到另外一個城市成了J最常作的事情。他有一個錢袋,用於存放往來城市間的路費。 10 11 聰明的J發現,若是不在某個城市停下來修整,在連續行進過程當中,他所花的路費與他已走過的距離有關,在走第x公里到第x+1公里這一公里中(x是整數),他花費的路費是x+10這麼多。也就是說走1公里花費11,走2公里要花費23。 12 13 J大臣想知道:他從某一個城市出發,中間不休息,到達另外一個城市,全部可能花費的路費中最可能是多少呢? 14 15 輸入格式 16 輸入的第一行包含一個整數n,表示包括首都在內的T王國的城市數 17 18 城市從1開始依次編號,1號城市爲首都。 19 20 接下來n-1行,描述T國的高速路(T國的高速路必定是n-1條) 21 22 每行三個整數Pi, Qi, Di,表示城市Pi和城市Qi之間有一條高速路,長度爲Di公里。 23 24 輸出格式 25 輸出一個整數,表示大臣J最多花費的路費是多少。 26 27 樣例輸入1 28 5 29 1 2 2 30 1 3 1 31 2 4 5 32 2 5 4 33 樣例輸出1 34 135 35 輸出格式 36 大臣J從城市4到城市5要花費135的路費。 37 */ 38 #include <stdio.h> 39 #include <string.h> 40 #include <math.h> 41 #include <stdlib.h> 42 43 struct node; 44 typedef struct node Node; 45 typedef Node *PtrToNode; 46 typedef PtrToNode List; 47 typedef PtrToNode Position; 48 49 struct node 50 { 51 int n; 52 int val; 53 Position next; 54 }; 55 56 int count=0; 57 int max=0; 58 int x; 59 int *visit; //是否已遍歷 60 61 Position Last(List l); //找出最後項 62 void Insert(int x,int q,List l,Position p); //在p後插入含x的項 63 void Dfs(int a,List l[]); //深度優先搜索 64 int Num(List l); 65 66 int main(void) 67 { 68 int n,u,v,q,a,b; 69 int i,j,k; 70 Node *head; 71 List *l,tmp; 72 Position p; 73 74 fscanf(stdin,"%d",&n); 75 head=(Node *)malloc(sizeof(Node)*(n+1)); 76 l=(List *)malloc(sizeof(List)*(n+1)); 77 visit=(int *)malloc(sizeof(int)*(n+1)); 78 79 for(i=0;i<=n;i++) //初始化表頭及鏈表 80 { 81 head[i].next=NULL; 82 l[i]=&head[i]; 83 } 84 85 for(i=1;i<=n-1;i++) //創建無向圖 86 { 87 fscanf(stdin,"%d%d%d",&u,&v,&q); 88 Insert(v,q,l[u],Last(l[u])); 89 Insert(u,q,l[v],Last(l[v])); 90 } 91 92 for(j=1;j<=n;j++) 93 visit[j]=0; 94 Dfs(1,l); //第一次遍歷,找到點a,用全局變量x保存 95 96 for(j=1;j<=n;j++) 97 visit[j]=0; 98 count=0; 99 max=0; 100 Dfs(x,l); //第二次遍歷,找到點b,用全局變量x保存,此時max爲最大距離 101 102 printf("%d",max*10+(max+1)*max/2); 103 104 return 0; 105 } 106 107 Position Last(List l) 108 { 109 Position p; 110 for(p=l;p->next!=NULL;p=p->next); 111 return p; 112 } 113 114 void Insert(int x,int q,List l,Position p) 115 { 116 Position tmp; 117 tmp=(Position) malloc(sizeof(Node)); 118 119 tmp->n=x; 120 tmp->val=q; 121 tmp->next=p->next; 122 p->next=tmp; 123 } 124 125 void Dfs(int a,List l[]) 126 { 127 Position p; 128 129 visit[a]=1; 130 for(p=l[a]->next;p!=NULL;p=p->next) 131 if(!(visit[p->n])) 132 { 133 count+=p->val; 134 if(count>max) 135 { 136 max=count; 137 x=p->n; 138 } 139 140 Dfs(p->n,l); 141 count-=p->val; 142 } 143 } 144 145 int Num(List l) 146 { 147 int n=0; 148 Position p; 149 for(p=l->next;p!=NULL;p=p->next) 150 n++; 151 return n; 152 }
1 /* 2 歷屆試題 幸運數 3 4 問題描述 5 幸運數是波蘭數學家烏拉姆命名的。它採用與生成素數相似的「篩法」生成 6 7 。 8 首先從1開始寫出天然數1,2,3,4,5,6,.... 9 10 1 就是第一個幸運數。 11 12 咱們從2這個數開始。把全部序號能被2整除的項刪除,變爲: 13 14 1 _ 3 _ 5 _ 7 _ 9 .... 15 16 把它們縮緊,從新記序,爲: 17 18 1 3 5 7 9 .... 。這時,3爲第2個幸運數,而後把全部能被3整除的序號位置的數刪去。注意,是序號位置,不是那個數自己可否被3整除!! 刪除的應該是5,11, 17, ... 19 20 此時7爲第3個幸運數,而後再刪去序號位置能被7整除的(19,39,...) 21 22 最後剩下的序列相似: 23 24 1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, ... 25 26 輸入格式 27 輸入兩個正整數m n, 用空格分開 (m < n < 1000*1000) 28 輸出格式 29 程序輸出 位於m和n之間的幸運數的個數(不包含m和n)。 30 樣例輸入1 31 1 20 32 樣例輸出1 33 5 34 樣例輸入2 35 30 69 36 樣例輸出2 37 8 38 */ 39 #include<stdio.h> 40 #define MAXN 1000010 41 int flag[MAXN]; 42 int m,n,a[MAXN],s[MAXN],size=0; 43 int fa(int k) 44 { 45 if(flag[k]) 46 return a[k]; 47 return fa(k-1); 48 } 49 int main() 50 { 51 int i, p, k, j; 52 scanf("%d%d",&m,&n); 53 for(i=1;i<=n;i+=2) 54 { 55 s[++size]=i; 56 flag[i]=1; 57 a[i]=size; 58 } 59 for(i=2;i<=size;i++) 60 { 61 int Mod=s[i],d=s[i]-1; 62 if(Mod>size) 63 break; 64 for(p=1,j=Mod;j<=size;j+=Mod,p++) 65 { 66 flag[s[j]]=0; 67 for(k=1;k<Mod&&k+j<=size;k++) 68 { 69 s[++d]=s[j+k]; 70 a[s[j+k]]-=p; 71 } 72 } 73 size=d; 74 } 75 printf("%d\n",fa(n-1)-fa(m)); 76 return 0; 77 }
歷屆試題(PartB-10題)
1 /* 2 歷屆試題 橫向打印二叉樹 3 4 問題描述 5 二叉樹能夠用於排序。其原理很簡單:對於一個排序二叉樹添加新節點時,先與根節點比較,若小則交給左子樹繼續處理,不然交給右子樹。 6 7 當遇到空子樹時,則把該節點放入那個位置。 8 9 好比,10 8 5 7 12 4 的輸入順序,應該建成二叉樹以下圖所示,其中.表示空白。 10 11 ...|-12 12 10-| 13 ...|-8-| 14 .......|...|-7 15 .......|-5-| 16 ...........|-4 17 本題目要求:根據已知的數字,創建排序二叉樹,並在標準輸出中橫向打印該二叉樹。 18 19 輸入格式 20 輸入數據爲一行空格分開的N個整數。 N<100,每一個數字不超過10000。 21 22 輸入數據中沒有重複的數字。 23 24 輸出格式 25 輸出該排序二叉樹的橫向表示。爲了便於評卷程序比對空格的數目,請把空格用句點代替: 26 27 樣例輸入1 28 10 5 20 29 樣例輸出1 30 ...|-20 31 10-| 32 ...|-5 33 樣例輸入2 34 5 10 20 8 4 7 35 樣例輸出2 36 .......|-20 37 ..|-10-| 38 ..|....|-8-| 39 ..|........|-7 40 5-| 41 ..|-4 42 43 */ 44 #include<stdio.h> 45 #include<stdlib.h> 46 #include<string.h> 47 48 typedef struct TNode 49 { 50 int key; 51 struct TNode *left; 52 struct TNode *right; 53 }TNode, *Tree; 54 55 Tree insert(Tree root, Tree src) 56 { 57 if(root == NULL) 58 { 59 root = src; 60 } 61 else if(src->key > root->key) 62 { 63 root->left = insert(root->left, src); 64 } 65 else 66 { 67 root->right = insert(root->right, src); 68 } 69 return root; 70 } 71 72 char l[1000]; 73 74 #define U 1 75 #define D 2 76 #define S ('.') 77 78 void print(Tree root, int s, int dir) 79 { 80 if(root != NULL) 81 { 82 int i; 83 char buf[10]; 84 sprintf(buf, "|-%d-", root->key); 85 int len = strlen(buf); 86 for(i = 0; i < len; i++) 87 { 88 l[s + i] = S; 89 } 90 if(dir == D) 91 { 92 l[s] = '|'; 93 } 94 print(root->left, s + len, U); 95 96 l[s] = '\0'; 97 if(root->left == NULL && root->right == NULL) 98 { 99 buf[len - 1] = '\0'; 100 printf("%s%s\n", l, buf); 101 } 102 else 103 { 104 printf("%s%s|\n", l, buf); 105 } 106 l[s] = S; 107 108 if(dir == U) 109 { 110 l[s] = '|'; 111 } 112 print(root->right, s + len, D); 113 l[s] = S; 114 } 115 } 116 117 void printPre(Tree root, int s) 118 { 119 if(root != NULL) 120 { 121 int i; 122 char buf[10]; 123 sprintf(buf, "%d-", root->key); 124 int len = strlen(buf); 125 for(i = 0; i < len; i++) 126 { 127 l[s + i] = S; 128 } 129 print(root->left, s + len, U); 130 131 printf("%s|\n", buf); 132 133 print(root->right, s + len, D); 134 } 135 } 136 137 int main(void) 138 { 139 int n; 140 Tree tree = NULL; 141 while(scanf("%d", &n) > 0) 142 { 143 Tree neo = malloc(sizeof(TNode)); 144 neo->key = n; 145 neo->left = neo->right = NULL; 146 tree = insert(tree, neo); 147 } 148 printPre(tree, 0); 149 return 0; 150 }
1 /* 2 歷屆試題 危險係數 3 4 問題描述 5 抗日戰爭時期,冀中平原的地道戰曾發揮重要做用。 6 7 地道的多個站點間有通道鏈接,造成了龐大的網絡。但也有隱患,當敵人發現了某個站點後,其它站點間可能所以會失去聯繫。 8 9 咱們來定義一個危險係數DF(x,y): 10 11 對於兩個站點x和y (x != y), 若是能找到一個站點z,當z被敵人破壞後,x和y不連通,那麼咱們稱z爲關於x,y的關鍵點。相應的,對於任意一對站點x和y,危險係數DF(x,y)就表示爲這兩點之間的關鍵點個數。 12 13 本題的任務是:已知網絡結構,求兩站點之間的危險係數。 14 15 輸入格式 16 輸入數據第一行包含2個整數n(2 <= n <= 1000), m(0 <= m <= 2000),分別表明站點數,通道數; 17 18 接下來m行,每行兩個整數 u,v (1 <= u, v <= n; u != v)表明一條通道; 19 20 最後1行,兩個數u,v,表明詢問兩點之間的危險係數DF(u, v)。 21 22 輸出格式 23 一個整數,若是詢問的兩點不連通則輸出-1. 24 樣例輸入 25 7 6 26 1 3 27 2 3 28 3 4 29 3 5 30 4 5 31 5 6 32 1 6 33 樣例輸出 34 2 35 */ 36 #include<stdio.h> 37 #include<stdlib.h> 38 struct Node 39 { 40 int data; 41 struct Node *pNext; 42 }; 43 struct Node tab[1001]; 44 int visit[1001]={0}; 45 int way[1001]={0}; 46 int count[1001]={0}; 47 int cnt=0; 48 void Insert(int n,int x); 49 void Init(int n); 50 void dfs(int x,int y,int n); 51 int fun(int n); 52 int main() 53 { 54 int x,y,n,m,u,v; 55 scanf("%d%d",&n,&m); 56 Init(n); 57 while(m--) 58 { 59 scanf("%d%d",&u,&v); 60 Insert(u,v); 61 Insert(v,u); 62 } 63 scanf("%d%d",&x,&y); 64 dfs(x,y,0); 65 int ret=fun(n); 66 printf("%d\n",ret); 67 return 0; 68 } 69 int fun(int n) 70 { 71 int i; 72 int ret=0; 73 for(i=1;i<=n;i++) 74 { 75 if(count[i]==cnt) 76 { 77 ret++; 78 } 79 } 80 return (ret-2); 81 } 82 void dfs(int x,int y,int n) 83 { 84 visit[x]=1; 85 way[n]=x; 86 struct Node *p=&tab[x]; 87 if(x==y) 88 { 89 int i; 90 cnt++; 91 for(i=0;i<=n;i++) 92 { 93 count[way[i]]++; 94 } 95 return ; 96 } 97 while((p=p->pNext)!=NULL) 98 { 99 if(visit[p->data]!=1) 100 { 101 dfs(p->data,y,n+1); 102 visit[p->data]=0; 103 } 104 } 105 } 106 void Init(int n) 107 { 108 int i; 109 for(i=1;i<=n;i++) 110 { 111 tab[i].data=i; 112 tab[i].pNext=NULL; 113 } 114 } 115 116 void Insert(int n,int x) 117 { 118 struct Node *p=&tab[n]; 119 while(p->pNext!=NULL) 120 { 121 p=p->pNext; 122 } 123 struct Node *new=(struct Node *)malloc(sizeof(struct Node)); 124 p->pNext=new; 125 new->data=x; 126 new->pNext=NULL; 127 }
1 /* 2 歷屆試題 網絡尋路 3 4 問題描述 5 X 國的一個網絡使用若干條線路鏈接若干個節點。節點間的通訊是雙向的。某重要數據包,爲了安全起見,必須剛好被轉發兩次到達目的地。該包可能在任意一個節點產生,咱們須要知道該網絡中一共有多少種不一樣的轉發路徑。 6 7 源地址和目標地址能夠相同,但中間節點必須不一樣。 8 9 以下圖所示的網絡。 10 11 圖爲123互連,235互連,2鏈接4 (直線鏈接) 12 13 14 1 -> 2 -> 3 -> 1 是容許的 15 16 1 -> 2 -> 1 -> 2 或者 1 -> 2 -> 3 -> 2 都是非法的。 17 18 輸入格式 19 輸入數據的第一行爲兩個整數N M,分別表示節點個數和鏈接線路的條數(1<=N<=10000; 0<=M<=100000)。 20 21 接下去有M行,每行爲兩個整數 u 和 v,表示節點u 和 v 聯通(1<=u,v<=N , u!=v)。 22 23 輸入數據保證任意兩點最多隻有一條邊鏈接,而且沒有本身連本身的邊,即不存在重邊和自環。 24 25 輸出格式 26 輸出一個整數,表示知足要求的路徑條數。 27 樣例輸入1 28 3 3 29 1 2 30 2 3 31 1 3 32 樣例輸出1 33 6 34 樣例輸入2 35 4 4 36 1 2 37 2 3 38 3 1 39 1 4 40 樣例輸出2 41 10 42 */ 43 #include<stdio.h> 44 #include<string.h> 45 #define MAXN 10010 46 #define MAXM 100010 47 int Du[MAXN],U[MAXM],V[MAXM]; 48 int main() 49 { 50 int n,i,m; 51 long long ans=0; 52 scanf("%d%d",&n,&m); 53 memset(Du,0,sizeof(Du)); 54 for(i=0;i<m;i++){ 55 scanf("%d%d",&U[i],&V[i]); 56 Du[U[i]]++; 57 Du[V[i]]++; 58 } 59 for(i=0;i<m;i++)if(Du[U[i]]>1&&Du[V[i]]>1)ans+=(Du[U[i]]-1)*(Du[V[i]]-1)*2; 60 printf("%I64d\n",ans); 61 return 0; 62 }
1 /* 2 歷屆試題 高僧鬥法 3 4 問題描述 5 古時喪葬活動中常常請高僧作法事。儀式結束後,有時會有「高僧鬥法」的趣味節目,以舒緩壓抑的氣氛。 6 節目大略步驟爲:先用糧食(通常是稻米)在地上「畫」出若干級臺階(表示N級浮屠)。又有若干小和尚隨機地「站」在某個臺階上。最高一級臺階必須站人,其它任意。(如圖1所示) 7 兩位參加遊戲的法師分別指揮某個小和尚向上走任意多級的臺階,但會被站在高級臺階上的小和尚阻擋,不能越過。兩個小和尚也不能站在同一臺階,也不能向低級臺階移動。 8 兩法師輪流發出指令,最後全部小和尚必然會都擠在高段臺階,不再能向上移動。輪到哪一個法師指揮時沒法繼續移動,則遊戲結束,該法師認輸。 9 對於已知的臺階數和小和尚的分佈位置,請你計算先發指令的法師該如何決策才能保證勝出。 10 輸入格式 11 輸入數據爲一行用空格分開的N個整數,表示小和尚的位置。臺階序號從1算起,因此最後一個小和尚的位置便是臺階的總數。(N<100, 臺階總數<1000) 12 輸出格式 13 輸出爲一行用空格分開的兩個整數: A B, 表示把A位置的小和尚移動到B位置。如有多個解,輸出A值較小的解,若無解則輸出-1。 14 樣例輸入 15 1 5 9 16 樣例輸出 17 1 4 18 樣例輸入 19 1 5 8 10 20 樣例輸出 21 1 3 22 */ 23 //參考藍橋杯貼吧 dezhonger 24 #include <stdio.h> 25 int main() 26 { 27 int a[105],b[105],i=0,j,k,count,sum; 28 char c; 29 while(1) 30 { 31 scanf("%d%c",&a[i++],&c); 32 if(c=='\n') 33 break; 34 } 35 count=i; 36 for(i = 0;i < count-1;i++) 37 b[i]=a[i+1]-a[i]-1; 38 b[count-1]=0; 39 sum=b[0]; 40 for(i = 2;i < count;i = i+2) 41 sum^=b[i]; 42 if(sum == 0) 43 printf("-1\n"); 44 else 45 { 46 for(i = 0;i < count;i++) 47 for(j = 1;j <= b[i];j++) 48 { 49 b[i] -= j; 50 if(i!=0) 51 b[i-1]+=j; 52 sum = b[0]; 53 for(k = 2;k < count;k = k+2) 54 sum ^= b[k]; 55 if(sum == 0) 56 { 57 printf("%d %d\n",a[i],a[i]+j); 58 break; 59 } 60 b[i] += j; 61 if(i != 0) 62 b[i-1] -= j; 63 } 64 } 65 return 0; 66 } 67 68 /* 69 1 3 5 7 12 14 17 26 38 45 66 100 70 66 84 71 */
1 /* 2 歷屆試題 格子刷油漆 3 4 問題描述 5 X國的一段古城牆的頂端能夠當作 2*N個格子組成的矩形(以下圖所示),現須要把這些格子刷上保護漆。 6 7 圖爲由2X3個小矩形拼成的大矩形格子,上三個矩形依次爲a,c,e,下三個矩形依次爲b,d,f 8 城牆寬度爲2格(即上下兩層矩形),長度未知,此時爲3 9 10 你能夠從任意一個格子刷起,刷完一格,能夠移動到和它相鄰的格子(對角相鄰也算數),但不能移動到較遠的格子(由於油漆未乾不能踩!) 11 好比:a d b c e f 就是合格的刷漆順序。 12 c e f d a b 是另外一種合適的方案。 13 當已知 N 時,求總的方案數。當N較大時,結果會迅速增大,請把結果對 1000000007 (十億零七) 取模。 14 輸入格式 15 輸入數據爲一個正整數(不大於1000) 16 輸出格式 17 輸出數據爲一個正整數。 18 樣例輸入 19 2 20 樣例輸出 21 24 22 樣例輸入 23 3 24 樣例輸出 25 96 26 樣例輸入 27 22 28 樣例輸出 29 359635897 30 */ 31 #include <stdio.h> 32 long long a[1001],b[1001],sum; 33 #define NUM 1000000007 34 int main() 35 { 36 int i,n; 37 scanf("%d",&n); 38 b[1]=1; 39 for (i=2;i<=n;i++) 40 b[i]=(b[i-1]*2%NUM); 41 a[1]=1;a[2]=6; 42 for (i=3;i<=n;i++) 43 a[i]=(2*a[i-1]+b[i]+4*a[i-2])%NUM; 44 sum=4*a[n]; 45 for (i=2;i<n;i++) 46 sum=((sum+8*b[n-i]*a[i-1]%NUM)%NUM+(8*a[n-i]*b[i-1])%NUM)%NUM; 47 printf("%I64d\n",sum); 48 return 0; 49 }
1 /* 2 歷屆試題 農場陽光 3 4 問題描述 5 X星球十分特殊,它的自轉速度與公轉速度相同,因此陽光老是以固定的角度照射。 6 最近,X星球爲發展星際旅遊業,把空間位置出租給Y國遊客來曬太陽。每一個租位是漂浮在空中的圓盤形彩雲(圓盤與地面平行)。固然,這會遮擋住部分陽光,被遮擋的土地植物沒法生長。 7 本題的任務是計算某個農場宜於做物生長的土地面積有多大。 8 輸入格式 9 輸入數據的第一行包含兩個整數a, b,表示某農場的長和寬分別是a和b,此時,該農場的範圍是由座標(0, 0, 0), (a, 0, 0), (a, b, 0), (0, b, 0)圍成的矩形區域。 10 第二行包含一個實數g,表示陽光照射的角度。簡單起見,咱們假設陽光光線是垂直於農場的寬的,此時正好和農場的長的夾角是g度,此時,空間中的一點(x, y, z)在地面的投影點應該是(x + z * ctg(g度), y, 0),其中ctg(g度)表示g度對應的餘切值。 11 第三行包含一個非負整數n,表示空中租位個數。 12 接下來 n 行,描述每一個租位。其中第i行包含4個整數xi, yi, zi, ri,表示第i個租位彩雲的圓心在(xi, yi, zi)位置,圓半徑爲ri。 13 輸出格式 14 要求輸出一個實數,四捨五入保留兩位有效數字,表示農場裏能長莊稼的土地的面積。 15 樣例輸入 16 10 10 17 90.0 18 1 19 5 5 10 5 20 樣例輸出 21 21.46 22 樣例輸入 23 8 8 24 90.0 25 1 26 4 4 10 5 27 樣例輸出 28 1.81 29 樣例輸入 30 20 10 31 45.0 32 2 33 5 0 5 5 34 8 6 14 6 35 樣例輸出 36 130.15 37 */ 38 39 //該題未解決,若有解答出請給個思路參考下,謝謝
1 /* 2 歷屆試題 約數倍數選卡片 3 4 問題描述 5 閒暇時,福爾摩斯和華生玩一個遊戲: 6 在N張卡片上寫有N個整數。兩人輪流拿走一張卡片。要求下一我的拿的數字必定是前一我的拿的數字的約數或倍數。例如,某次福爾摩斯拿走的卡片上寫着數字「6」,則接下來華生能夠拿的數字包括: 7 1,2,3, 6,12,18,24 .... 8 當輪到某一方拿卡片時,沒有知足要求的卡片可選,則該方爲輸方。 9 請你利用計算機的優點計算一下,在已知全部卡片上的數字和可選哪些數字的條件下,怎樣選擇才能保證必勝! 10 當選多個數字均可以必勝時,輸出其中最小的數字。若是不管如何都會輸,則輸出-1。 11 輸入格式 12 輸入數據爲2行。第一行是若干空格分開的整數(每一個整數介於1~100間),表示當前剩餘的全部卡片。 13 第二行也是若干空格分開的整數,表示能夠選的數字。固然,第二行的數字必須徹底包含在第一行的數字中。 14 輸出格式 15 程序則輸出必勝的招法!! 16 樣例輸入 17 2 3 6 18 3 6 19 樣例輸出 20 3 21 樣例輸入 22 1 2 2 3 3 4 5 23 3 4 5 24 樣例輸出 25 4 26 */ 27 #include <iostream> 28 #include <fstream> 29 #include <cstdio> 30 #include <cstring> 31 #include <algorithm> 32 #include <queue> 33 #include <stack> 34 #include <climits> 35 #include <ctime> 36 #include <cmath> 37 #include <set> 38 #include <map> 39 #include <string> 40 #include <vector> 41 #define MAX(a,b) ((a)>(b)?(a):(b)) 42 #define MIN(a,b) ((a)<(b)?(a):(b)) 43 #define abs(x) ((x)>0?(x):(-(x))) 44 #define FOR(i,a,b) for(int i = (a);i<=(b);i++) 45 #define FORD(i,a,b) for(int i = (a);i>=(b);i--) 46 #define REP(i,n) for(int i = 0;i<(n);i++) 47 #define rst(x,k) memset(x,k,sizeof(x)) 48 #define lowbit(x) ((x)&(-(x))) 49 //#define h(x) (1<<(x)) 50 //#define lson (ind<<1) 51 //#define rson (ind<<1|1) 52 #define eps 1e-6 53 #define INF 140000000 54 #define maxn 5000 55 #define mod 1000000007 56 #define Pi acos(-1.0) 57 #define link fjksldfjaslkdfjas 58 using namespace std; 59 typedef long long LL; 60 int a[maxn] , b[maxn]; 61 int visit[maxn]; 62 char ss[maxn]; 63 struct node{ 64 int t,nxt; 65 }edge[maxn << 2]; 66 int headline[maxn] , E , n , tot; 67 void add(int f,int t){ 68 edge[E].t = t; 69 edge[E].nxt = headline[f]; 70 headline[f] = E++; 71 } 72 bool dfs(int u){ 73 bool ok = true; 74 visit[u] = true; 75 for(int i = headline[u];~i;i = edge[i].nxt){ 76 int v = edge[i].t; 77 if(!visit[v]){ 78 if(dfs(v)){ 79 ok = false; 80 break; 81 } 82 } 83 } 84 visit[u] = false; 85 if(ok == false)return false; 86 return true; 87 } 88 void solve(void){ 89 n = 0; tot = 0; 90 int len = strlen(ss) , temp = 0; 91 rst(headline,-1); E = 0; rst(visit,false); 92 bool finish = true; 93 REP(i,len){ 94 if(ss[i] <= '9' && ss[i] >= '0'){ 95 temp *= 10; 96 temp += ss[i] - '0'; 97 finish = false; 98 }else if(!finish){ 99 finish = true; 100 n++; a[n] = temp; 101 temp = 0; 102 } 103 } 104 if(!finish){ 105 n++; a[n] = temp; 106 finish = true; 107 temp = 0; 108 } 109 gets(ss); 110 len = strlen(ss); 111 REP(i,len){ 112 if(ss[i] <= '9' && ss[i] >= '0'){ 113 temp *= 10; 114 temp += ss[i] - '0'; 115 finish = false; 116 }else if(!finish){ 117 finish = true; 118 tot++; b[tot] = temp; 119 temp = 0; 120 } 121 } 122 if(!finish){ 123 tot++; b[tot] = temp; 124 finish = true; 125 temp = 0; 126 } 127 sort(a+1,a+n+1); 128 sort(b+1,b+tot+1); 129 //FOR(i,1,n)printf("%d ",a[i]);printf("\n"); 130 //FOR(i,1,tot)printf("%d ",b[i]);printf("\n"); 131 FOR(i,1,n){ 132 FOR(j,i+1,n){ 133 if(a[i] % a[j] == 0 || a[j] % a[i] == 0){ 134 add(i,j); add(j,i); 135 } 136 } 137 } 138 FOR(i,1,tot){ 139 FOR(j,1,n){ 140 if(b[i] == a[j]){ 141 if(dfs(j)){ 142 printf("%d\n",a[j]); 143 return; 144 } 145 break; 146 } 147 } 148 } 149 printf("-1\n"); 150 } 151 int main(void){ 152 while(gets(ss)) solve(); 153 return 0; 154 }
1 /* 2 歷屆試題 車輪軸跡 3 4 問題描述 5 棟棟天天騎自行車回家須要通過一條狹長的林蔭道。道路因爲年久失修,變得很是不平整。雖然棟棟每次都很顛簸,但他仍把騎車通過林蔭道當成一種樂趣。 6 因爲顛簸,棟棟騎車回家的路徑是一條上下起伏的曲線,棟棟想知道,他回家的這條曲線的長度到底是多長呢?更準確的,棟棟想知道從林蔭道的起點到林蔭道的終點,他的車前輪的軸(圓心)通過的路徑的長度。 7 棟棟對路面進行了測量。他把道路簡化成一條條長短不等的直線段,這些直線段首尾相連,且位於同一平面內。並在該平面內創建了一個直角座標系,把全部線段的端點座標都計算好。 8 假設棟棟的自行車在行進的過程當中前輪一直是貼着路面前進的。 9 10 圖片請百度 11 12 上圖給出了一個簡單的路面的例子,其中藍色實線爲路面,紅色虛線爲車輪軸通過的路徑。在這個例子中,棟棟的前輪軸從A點出發,水平走到B點,而後繞着地面的F點到C點(繞出一個圓弧),再沿直線下坡到D點,最後水平走到E點,在這個圖中地面的座標依次爲:(0, 0), (2, 0), (4, -1), (6, -1),前輪半徑爲1.50,前輪軸前進的距離依次爲: 13 AB=2.0000;弧長BC=0.6955;CD=1.8820;DE=1.6459。 14 總長度爲6.2233。 15 16 下圖給出了一個較爲複雜的路面的例子,在這個例子中,車輪在第一個下坡還沒下完時(D點)就開始上坡了,以後在坡的頂點要從E繞一個較大的圓弧到F點。這個圖中前輪的半徑爲1,每一段的長度依次爲: 17 AB=3.0000;弧長BC=0.9828;CD=1.1913;DE=2.6848;弧長EF=2.6224; FG=2.4415;GH=2.2792。 18 總長度爲15.2021。 19 20 圖片請百度 21 22 如今給出了車輪的半徑和路面的描述,請求出車輪軸軌跡的總長度。 23 輸入格式 24 輸入的第一行包含一個整數n和一個實數r,用一個空格分隔,表示描述路面的座標點數和車輪的半徑。 25 接下來n行,每一個包含兩個實數,其中第i行的兩個實數x[i], y[i]表示描述路面的第i個點的座標。 26 路面定義爲全部路面座標點順次鏈接起來的折線。給定的路面的必定知足如下性質: 27 28 *第一個座標點必定是(0, 0); 29 *第一個點和第二個點的縱座標相同; 30 *倒數第一個點和倒數第二個點的縱座標相同; 31 *第一個點和第二個點的距離很多於車輪半徑; 32 *倒數第一個點和倒數第二個點的的距離很多於車輪半徑; 33 *後一個座標點的橫座標大於前一個座標點的橫座標,即對於全部的i,x[i+1]>x[i]。 34 輸出格式 35 輸出一個實數,四捨五入保留兩個小數,表示車輪軸通過的總長度。 36 你的結果必須和參考答案如出一轍才能得分。數據保證答案精確值的小數點後第三位不是4或5。 37 樣例輸入 38 4 1.50 39 0.00 0.00 40 2.00 0.00 41 4.00 -1.00 42 6.00 -1.00 43 樣例輸出 44 6.22 45 樣例說明 46 這個樣例對應第一個圖。 47 樣例輸入 48 6 1.00 49 0.00 0.00 50 3.00 0.00 51 5.00 -3.00 52 6.00 2.00 53 7.00 -1.00 54 10.00 -1.00 55 樣例輸出 56 15.20 57 樣例說明 58 這個樣例對應第二個圖 59 數據規模和約定 60 對於20%的數據,n=4; 61 對於40%的數據,n≤10; 62 對於100%的數據,4≤n≤100,0.5≤r≤20.0,x[i] ≤2000.0,-2000.0≤y[i] ≤2000.0。 63 64 */ 65 #include <iostream> 66 #include <cstdlib> 67 #include <cstdio> 68 #include <cstring> 69 #include <vector> 70 #include <cmath> 71 #include <algorithm> 72 73 74 using namespace std; 75 76 const int MAXN = 10000; 77 const double PI = atan(1.0) * 4; 78 const double EPS = 1e-10; 79 80 class Point { 81 public: 82 double x, y; 83 Point() {} 84 Point(double x, double y) : x(x), y(y) {} 85 Point operator - (const Point &r) const { return Point(x-r.x, y-r.y); } 86 Point operator + (const Point &r) const { return Point(x+r.x, y+r.y); } 87 Point &operator += (const Point &r) { x += r.x; y += r.y; return *this; } 88 Point &operator *= (double m) { x *= m; y *= m; return *this; } 89 Point pOfRotate(double angle) const { 90 double cosA = cos(angle); 91 double sinA = sin(angle); 92 return Point(cosA*x-sinA*y, sinA*x+cosA*y); 93 } 94 Point pOfRotate90() const { return Point(-y, x); } 95 double length() const { return sqrt(x*x+y*y); } 96 Point pOfNormal() const { 97 double len = length(); 98 return Point(x/len, y/len); 99 } 100 double angle() const { return atan2(y, x); } 101 }; 102 103 ostream & operator <<(ostream &os, const Point &v) 104 { 105 os << "(" << v.x << "," << v.y << ")"; 106 return os; 107 } 108 109 class Segment; 110 class Circle; 111 112 class Seg { 113 public: 114 virtual double getLeft() const = 0; 115 virtual double getRight() const = 0; 116 virtual double getY(double x) const = 0; 117 virtual double getLength(double x1, double x2) const = 0; 118 virtual void intersect(Seg *r) const = 0; 119 virtual void intersect(const Segment &v) const = 0; 120 virtual void intersect(const Circle &v) const = 0; 121 bool contains(double x) const { return x>=getLeft() && x<=getRight(); } 122 virtual void acceptPrint(ostream &os) const = 0; 123 }; 124 125 ostream & operator <<(ostream &os, const Seg &v) 126 { 127 v.acceptPrint(os); 128 return os; 129 } 130 131 Point intersectRet[4]; 132 int tIntersectRet; 133 134 class Segment : public Seg { 135 public: 136 Point a, b; 137 Segment &moveLeft(double dis) 138 { 139 Point tmp = ((b-a).pOfRotate90().pOfNormal() *= dis); 140 a += tmp; 141 b += tmp; 142 return *this; 143 } 144 virtual double getLeft() const { return a.x; } 145 virtual double getRight() const { return b.x; } 146 virtual double getY(double x) const { 147 return (x-a.x)*(b.y-a.y)/(b.x-a.x)+a.y; 148 } 149 virtual double getLength(double x1, double x2) const { 150 return (x2-x1) * (b-a).length() / (b.x-a.x); 151 } 152 virtual void intersect(Seg *r) const { 153 r->intersect(*this); 154 } 155 virtual void intersect(const Segment &v) const { 156 tIntersectRet = 0; 157 double ang = (b-a).angle(); 158 Point c = (v.a-a).pOfRotate(-ang); 159 Point d = (v.b-a).pOfRotate(-ang); 160 // Bug 161 //double di = b.length(); 162 double di = (b-a).length(); 163 if (!((c.y>0&&d.y<0) || (c.y<0&&d.y>0))) 164 return ; 165 double x = (d.x-c.x) * (-c.y) / (d.y-c.y) + c.x; 166 if (x<0 || x>di) 167 return ; 168 Point ret = Point(x,0).pOfRotate(ang)+a; 169 intersectRet[tIntersectRet++] = ret; 170 } 171 virtual void intersect(const Circle &v) const; 172 virtual void acceptPrint(ostream &os) const { 173 os << a << "-" << b; 174 } 175 }; 176 177 class Circle : public Seg { 178 public: 179 Point c; 180 double r; 181 virtual double getLeft() const { return c.x - r; } 182 virtual double getRight() const { return c.x + r; } 183 virtual double getY(double x) const { 184 double y2 = r * r - (c.x - x) * (c.x - x); 185 if (y2<0) y2 = 0; 186 return c.y + sqrt(y2); 187 } 188 virtual double getLength(double x1, double x2) const { 189 x1 -= c.x; x2 -= c.x; 190 double a1 = Point(x1, sqrt(abs(r*r-x1*x1))).angle(), a2 = Point(x2, sqrt(abs(r*r-x2*x2))).angle(); 191 return (a1-a2) * r; 192 } 193 virtual void intersect(Seg *r) const { 194 r->intersect(*this); 195 } 196 virtual void intersect(const Segment &v) const { 197 tIntersectRet = 0; 198 Point a = v.a - c; 199 Point b = v.b - c; 200 double ang = (b-a).angle(); 201 Point nA = a.pOfRotate(-ang); 202 Point nB = b.pOfRotate(-ang); 203 double y = nA.y; 204 if (y>r || y<-r) 205 return ; 206 double x = sqrt(r*r - y*y); 207 if (x>=nA.x && x<=nB.x) 208 intersectRet[tIntersectRet++] = Point(x, y).pOfRotate(ang) + c; 209 if (-x>=nA.x && -x<=nB.x) 210 intersectRet[tIntersectRet++] = Point(-x, y).pOfRotate(ang) + c; 211 } 212 virtual void intersect(const Circle &v) const { 213 tIntersectRet = 0; 214 Point p = v.c - c; 215 double d = p.length(); 216 if (d > r + v.r || d==0) 217 return ; 218 double x = (r*r - v.r*v.r + d*d) / (2*d); 219 if (x <= r) 220 { 221 double y = sqrt(abs(r*r - x*x)); 222 double ang = p.angle(); 223 intersectRet[tIntersectRet++] = Point(x,y).pOfRotate(ang) + c; 224 intersectRet[tIntersectRet++] = Point(x,-y).pOfRotate(ang) + c; 225 } 226 } 227 virtual void acceptPrint(ostream &os) const { 228 os << c << "," << r; 229 } 230 }; 231 232 void Segment::intersect(const Circle &v) const { 233 v.intersect(*this); 234 } 235 236 int n; 237 Point inps[MAXN]; 238 vector<Seg *> segs; 239 vector<double> spes; 240 double radius = 1; 241 242 void input() 243 { 244 scanf("%d%lf", &n, &radius); 245 for (int i = 0; i < n; ++i) 246 { 247 double x, y; 248 scanf("%lf%lf", &x, &y); 249 inps[i] = Point(x, y); 250 } 251 } 252 253 void process() 254 { 255 segs.clear(); 256 spes.clear(); 257 for (int i = 1; i + 1 < n; ++i) 258 { 259 Circle *tmp = new Circle; 260 tmp->c = inps[i]; 261 tmp->r = radius; 262 segs.push_back(tmp); 263 } 264 for (int i = 0; i + 1 < n; ++i) 265 { 266 Segment *tmp = new Segment; 267 tmp->a = inps[i]; 268 tmp->b = inps[i+1]; 269 tmp->moveLeft(radius); 270 segs.push_back(tmp); 271 } 272 for (int i = 0; i < (int)segs.size(); ++i) 273 { 274 spes.push_back(segs[i]->getLeft()); 275 spes.push_back(segs[i]->getRight()); 276 } 277 for (int i = 0; i < (int)segs.size(); ++i) 278 { 279 for (int j = i+1; j < (int)segs.size(); ++j) 280 { 281 segs[i]->intersect(segs[j]); 282 if (tIntersectRet > 0) 283 { 284 for (int id = 0; id < tIntersectRet; ++id) 285 { 286 //cout << *segs[i] << " " << *segs[j] << " : " << intersectRet[id] << endl; 287 spes.push_back(intersectRet[id].x); 288 } 289 } 290 } 291 } 292 sort(spes.begin(), spes.end()); 293 double pre = spes[0]; 294 const double NONE = 1e30; 295 double preEnd = NONE; 296 double totalLen = 0; 297 for (int i = 1; i < (int)spes.size(); ++i) 298 { 299 if (spes[i]-pre < EPS) 300 continue; 301 double cur = (pre+spes[i]) / 2; 302 //cout << "Processing " << cur << " from " << pre << " to " << spes[i] << endl; 303 if (cur>=inps[0].x && cur<=inps[n-1].x) 304 { 305 double MY = -NONE; 306 int who; 307 for (int j = 0; j < (int)segs.size(); ++j) 308 { 309 if (!segs[j]->contains(cur)) 310 continue; 311 double y = segs[j]->getY(cur); 312 if (y > MY) 313 { 314 MY = y; 315 who = j; 316 } 317 } 318 if (preEnd != NONE) 319 { 320 double LY = segs[who]->getY(pre); 321 //cout << "Drop info " << *segs[who] << " " << "[" << pre << "]" << endl; 322 totalLen += abs(preEnd-LY); 323 //cout << "Pre drop = " << abs(preEnd-LY) << " from " << preEnd << " to " << LY << endl; 324 } 325 double len = segs[who]->getLength(pre, spes[i]); 326 if (len < 0) 327 printf("Error!\n"); 328 //cout << "Curlen = " << len << " from " << pre << " to " << spes[i] << endl; 329 totalLen += len; 330 preEnd = segs[who]->getY(spes[i]); 331 } 332 pre = spes[i]; 333 } 334 printf("%0.2lf\n", totalLen); 335 for (int i = 0; i < (int)segs.size(); ++i) 336 delete segs[i]; 337 segs.clear(); 338 } 339 340 int main() 341 { 342 input(); 343 process(); 344 return 0; 345 }
1 /* 2 歷屆試題 九宮重排 3 4 問題描述 5 以下面第一個圖的九宮格中,放着 1~8 的數字卡片,還有一個格子空着。與空格子相鄰的格子中的卡片能夠移動到空格中。通過若干次移動,能夠造成第二個圖所示的局面。 6 7 圖爲2個9宮格,第一個爲123,456,78空格。第二個爲123,空格46,758。 8 9 咱們把第一個圖的局面記爲:12345678. 10 把第二個圖的局面記爲:123.46758 11 顯然是按從上到下,從左到右的順序記錄數字,空格記爲句點。 12 本題目的任務是已知九宮的初態和終態,求最少通過多少步的移動能夠到達。若是不管多少步都沒法到達,則輸出-1。 13 輸入格式 14 輸入第一行包含九宮的初態,第二行包含九宮的終態。 15 輸出格式 16 輸出最少的步數,若是不存在方案,則輸出-1。 17 樣例輸入 18 12345678. 19 123.46758 20 樣例輸出 21 3 22 樣例輸入 23 13524678. 24 46758123. 25 樣例輸出 26 22 27 */ 28 #include<stdio.h> 29 #include<stdlib.h> 30 #include<string.h> 31 typedef struct _Node 32 { 33 char tab[3][3]; 34 int x,y; 35 int no; 36 }Node,*pNode; 37 int vx[4]={-1,1,0,0}; 38 int vy[4]={0,0,-1,1}; 39 Node res[400000]; 40 int front=0,rear=0; 41 int vis[4000000],fact[9]; 42 43 void input(pNode start); 44 void bfs(pNode start,pNode end); 45 void init_lookup_table(); 46 int try_to_insert(int s); 47 int main() 48 { 49 Node start,end; 50 input(&start); 51 input(&end); 52 bfs(&start,&end); 53 printf("-1\n"); 54 return 0; 55 } 56 void input(pNode start) 57 { 58 int i,j; 59 for(i=0;i<3;i++) 60 { 61 for(j=0;j<3;j++) 62 { 63 scanf("%c",&( (start->tab)[i][j] )); 64 if((start->tab)[i][j]=='.') 65 { 66 start->x = i; 67 start->y = j; 68 } 69 } 70 } 71 start->no = 0; 72 getchar(); 73 } 74 void bfs(pNode start,pNode end) 75 { 76 int i,j; 77 char ch; 78 pNode tmp; 79 init_lookup_table(); 80 memcpy(&res[rear],start,sizeof(res[rear])); 81 try_to_insert(rear); 82 rear++; 83 while(front!=rear) 84 { 85 //printf("%d ",rear); 86 tmp = &res[front]; 87 if(memcmp(tmp->tab,end->tab,sizeof(end->tab))==0) 88 { 89 printf("%d\n",tmp->no); 90 exit(0); 91 } 92 int no = tmp->no; 93 for(i=0;i<4;i++) 94 { 95 int xx = tmp->x+vx[i]; 96 int yy = tmp->y+vy[i]; 97 if(xx>=0 && xx<3 && yy>=0 && yy<3) 98 { 99 pNode p = &res[rear]; 100 memcpy(p,tmp,sizeof(res[front])); 101 p->tab[tmp->x][tmp->y] = p->tab[xx][yy]; 102 p->tab[xx][yy] = tmp->tab[tmp->x][tmp->y]; 103 p->no = no+1; 104 p->x = xx; 105 p->y = yy; 106 if(try_to_insert(rear)) 107 { 108 rear++; 109 } 110 } 111 } 112 front++; 113 //printf("%d ",rear); 114 } 115 } 116 117 void init_lookup_table() 118 { 119 int i; 120 fact[0] = 1; 121 for(i=1;i<9;i++) 122 { 123 fact[i] = fact[i-1]*i; 124 } 125 } 126 127 int try_to_insert(int s) 128 { 129 int i,j; 130 int code = 0; 131 for(i=0;i<9;i++) 132 { 133 int cnt = 0; 134 for(j=i+1;j<9;j++) 135 { 136 if(res[s].tab[j/3][j%3] < res[s].tab[i/3][i%3]) 137 { 138 cnt++; 139 } 140 code += fact[8-i]*cnt; 141 } 142 } 143 if(vis[code]) 144 { 145 return 0; 146 } 147 return vis[code] = 1; 148 }
1 /* 2 歷屆試題 公式求值 3 4 問題描述 5 輸入n, m, k,輸出下面公式的值。 6 7 圖片請百度 8 9 其中C_n^m是組合數,表示在n我的的集合中選出m我的組成一個集合的方案數。組合數的計算公式以下。 10 11 圖片請百度 12 13 輸入格式 14 輸入的第一行包含一個整數n;第二行包含一個整數m,第三行包含一個整數k。 15 輸出格式 16 計算上面公式的值,因爲答案很是大,請輸出這個值除以999101的餘數。 17 樣例輸入 18 3 19 1 20 3 21 樣例輸出 22 162 23 樣例輸入 24 20 25 10 26 10 27 樣例輸出 28 359316 29 數據規模和約定 30 對於10%的數據,n≤10,k≤3; 31 對於20%的數據,n≤20,k≤3; 32 對於30%的數據,n≤1000,k≤5; 33 對於40%的數據,n≤10^7,k≤10; 34 對於60%的數據,n≤10^15,k ≤100; 35 對於70%的數據,n≤10^100,k≤200; 36 對於80%的數據,n≤10^500,k ≤500; 37 對於100%的數據,n在十進制下不超過1000位,即1≤n<10^1000,1≤k≤1000,同時0≤m≤n,k≤n。 38 提示 39 999101是一個質數; 40 當n位數比較多時,絕大多數狀況下答案都是0,但評測的時候會選取一些答案不是0的數據; 41 */ 42 43 //該題未解決