算法-藍橋杯習題(六)

藍橋杯習題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 //該題未解決 

 

GoToTheNextPart

相關文章
相關標籤/搜索