文章推薦
精選java等全套學習資源 精選java電子圖書資源 精選大數據學習資源 java項目練習精選
藍橋杯練習系統習題-算法訓練3
題目搜索方式:Ctrl+F—-> 輸入題目名稱—>定位到解答.
入門訓練(詳見 算法-藍橋杯習題(1-1))
基礎練習(詳見 算法-藍橋杯習題(2-1))
基礎練習(詳見 算法-藍橋杯習題(2-2))
算法訓練(詳見 算法-藍橋杯習題(3-1))
算法訓練(詳見 算法-藍橋杯習題(3-2))
算法訓練(詳見 算法-藍橋杯習題(3-3))
算法訓練(詳見 算法-藍橋杯習題(3-4))
算法訓練(詳見 算法-藍橋杯習題(3-5))
算法訓練(詳見 算法-藍橋杯習題(3-6))
算法提高(詳見 算法-藍橋杯習題(4-1))
算法提高(詳見 算法-藍橋杯習題(4-2))
歷屆試題(詳見 算法-藍橋杯習題(5-1))
歷屆試題(詳見 算法-藍橋杯習題(5-2))
算法訓練 彈彈堂
問題描述 XX無聊玩彈彈堂,戰斗力太低啦! 輸入格式 測試數據的輸入一定會滿足的格式。 例:輸入的第一行包含兩個整數n, m,分別表示矩陣的行數和列數。接下來n行,每行m個正整數,表示輸入的矩陣。 輸出格式 要求用戶的輸出滿足的格式。 例:輸出1行,包含一個整數,表示矩陣中所有元素的和。 樣例輸入 一個滿足題目要求的輸入范例。 例: 2 2 1 2 3 4 樣例輸出 與上面的樣例輸入對應的輸出。 例: 10 數據規模和約定 輸入數據中每一個數的范圍。 例:0<n,m<100, 0<=矩陣中的每個數<=1000。
#include <stdio.h> main() {
printf (
"1.54545" );
return 0 ; }
算法訓練 送分啦
問題描述 這題想得分嗎?想,請輸出“yes”;不想,請輸出“no”。 輸出格式 輸出包括一行,為“yes”或“no”。
#include <stdio.h> main() {
printf (
"yes\n" );
return 0 ; }
算法訓練 A+B Problem
問題描述 輸入A,B。 輸出A+B。 輸入格式 輸入包含兩個整數A,B,用一個空格分隔。 輸出格式 輸出一個整數,表示A+B的值。 樣例輸入 5 8 樣例輸出 13 數據規模和約定 -1,000,000,000<=A,B<=1,000,000,000。
#include <stdio.h> main() {
long long int A,B;
scanf (
"%lld%lld" ,&A,&B);
printf (
"%lld\n" ,A+B);
return 0 ; }
算法訓練 采油區域
采油區域 Siruseri政府決定將石油資源豐富的Navalur省的土地拍賣給私人承包商以建立油井。被拍賣的整塊土地為一個矩形區域,被劃分為M×N個小塊。 Siruseri地質調查局有關于Navalur土地石油儲量的估測數據。這些數據表示為M×N個非負整數,即對每一小塊土地石油儲量的估計值。 為了避免出現壟斷,政府規定每一個承包商只能承包一個由K×K塊相連的土地構成的正方形區域。 AoE石油聯合公司由三個承包商組成,他們想選擇三塊互不相交的K×K的區域使得總的收益最大。 例如,假設石油儲量的估計值如下:
無圖
如果K = 2, AoE公司可以承包的區域的石油儲量總和為100, 如果K = 3, AoE公司可以承包的區域的石油儲量總和為208。 AoE公司雇傭你來寫一個程序,幫助計算出他們可以承包的區域的石油儲量之和的最大值。 輸入格式 輸入第一行包含三個整數M, N, K,其中M和N是矩形區域的行數和列數,K是每一個承包商承包的正方形的大小(邊長的塊數)。接下來M行,每行有N個非負整數表示這一行每一小塊土地的石油儲量的估計值。 輸出格式 輸出只包含一個整數,表示AoE公司可以承包的區域的石油儲量之和的最大值。 數據規模和約定 數據保證K≤M且K≤N并且至少有三個K×K的互不相交的正方形區域。其中30%的輸入數據,M, N≤ 12。所有的輸入數據, M, N≤ 1500。每一小塊土地的石油儲量的估計值是非負整數且≤ 500。 樣例輸入 9 9 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 8 8 8 8 1 1 1 1 8 8 8 8 8 1 1 1 1 8 8 8 8 8 1 1 1 1 1 1 1 8 8 8 1 1 1 1 1 1 1 1 8 8 8 1 1 1 1 1 1 9 9 9 1 1 1 1 1 1 9 9 9 樣例輸出 208
#include <cstdio> #include <cstdlib> #include <algorithm> #include <string> #define max(a, b) ((a) > (b) ? (a) : (b)) #define max3(a, b, c) (max((a), max(b, c))) const char fi[] =
"oil.in" ;
const char fo[] =
"oil.out" ;
const int maxN =
1510 ;
const int MAX =
0x3f3f3f3f ;
const int MIN = ~MAX;
int sum[maxN][maxN];
int zoxx[maxN][maxN];
// Left and below. int zouh[maxN][maxN];
// Left and above. int yzxx[maxN][maxN];
// Right and below. int yzuh[maxN][maxN];
// Right and above. int hh[maxN];
// Horizon. int lp[maxN];
// Vertical. int n,m,K;
void init_file () {
return ; }
inline int getint () {
int res =
0 ;
char tmp;
while (!
isdigit (tmp = getchar()));
do res = (res <<
3 ) + (res <<
1 ) + tmp -
'0' ;
while (
isdigit (tmp = getchar()));
return res; }
void readdata () { n = getint(); m = getint(); K = getint();
for (
int i =
1 ; i < n +
1 ; ++i)
for (
int j =
1 ; j < m +
1 ; ++j) (sum[i][j] = getint()) += sum[i][j -
1 ];
for (
int i =
1 ; i < n +
1 ; ++i)
for (
int j =
1 ; j < m +
1 ; ++j) sum[i][j] += sum[i -
1 ][j];
//預處理出二維的前綴和。 for (
int i = K; i < n +
1 ; ++i)
for (
int j = K; j < m +
1 ; ++j) { zouh[i][j] = sum[i][j] + sum[i - K][j - K] - sum[i][j - K] - sum[i - K][j]; hh[i] = max(hh[i],zouh[i][j]);
//Horizon. lp[j] = max(lp[j],zouh[i][j]);
//Vertical. zouh[i][j] = max3(zouh[i][j], zouh[i -
1 ][j], zouh[i][j -
1 ]); }
// Left and above. for (
int i = n - K +
1 ; i; --i)
for (
int j = m - K +
1 ; j; --j) yzxx[i][j] = max3(sum[i -
1 ][j -
1 ] + sum[i + K -
1 ][j + K -
1 ] - sum[i -
1 ][j + K -
1 ] - sum[i + K -
1 ][j -
1 ], yzxx[i +
1 ][j], yzxx[i][j +
1 ]);
//Right and below. for (
int i = K; i < n +
1 ; ++i)
for (
int j = m - K +
1 ; j; --j) yzuh[i][j] = max3(sum[i][j + K -
1 ] + sum[i - K][j -
1 ] - sum[i][j -
1 ] - sum[i - K][j + K -
1 ], yzuh[i -
1 ][j], yzuh[i][j +
1 ]);
//Right and above. for (
int i = n - K +
1 ; i; --i)
for (
int j = K; j < m +
1 ; ++j) zoxx[i][j] = max3(sum[i -
1 ][j - K] + sum[i + K -
1 ][j] - sum[i -
1 ][j] - sum[i + K -
1 ][j - K], zoxx[i +
1 ][j], zoxx[i][j -
1 ]);
//Left and below return ; }
void work () {
int ans =
0 ;
for (
int i = K; i < n - (K <<
1 ); ++i) ans = max(ans,yzuh[i][
1 ] + hh[i + K] + yzxx[i + K +
1 ][
1 ]);
// Case 1. for (
int j = K; j < m - (K <<
1 ); ++j) ans = max(ans,zoxx[
1 ][j] + lp[j + K] + yzxx[
1 ][j + K +
1 ]);
// Case 2. for (
int i = K; i < n - K +
1 ; ++i)
for (
int j = K; j < m - K +
1 ; ++j) { ans = max3(ans,zouh[i][j] + yzuh[i][j +
1 ] + yzxx[i +
1 ][
1 ],
//Case 3. yzuh[i][
1 ] + zoxx[i +
1 ][j] + yzxx[i +
1 ][j +
1 ]);
//Case 4. ans = max3(ans,zouh[i][j] + zoxx[i +
1 ][j] + yzxx[
1 ][j +
1 ],
//Case 5. zoxx[
1 ][j] + yzuh[i][j +
1 ] + yzxx[i +
1 ][j +
1 ]);
//Case 6. }
printf (
"%d\n" ,ans);
return ; }
int main () { init_file(); readdata(); work();
return 0 ; }
#undef max
算法訓練 調和數列問題
問題描述 輸入一個實數x,求最小的n使得,1/2+1/3+1/4+…+1/(n+1)>=x。
輸入的實數x保證大于等于0.01,小于等于5.20,并且恰好有兩位小數。你的程序要能夠處理多組數據,即不停地讀入x,如果x不等于0.00,則計算答案,否則退出程序。
輸出格式為對于一個x,輸出一行n card(s)。其中n表示要計算的答案。 輸入格式 分行輸入x的具體數值 輸出格式 分行輸出n的數值,格式為n card(s) 樣例輸入 1.00 3.71 0.04 5.19 0.00
樣例輸出
3 card(s) 61 card(s) 1 card(s) 273 card(s)
#include <stdio.h> int main (void ) {
int i;
double n,k,s;
scanf (
"%lf" ,&n);
while (n!=
0 ) { s=
0 ;
for (i=
2 ;
1 ;i++) { k=
1.0 /i; s+=k;
if (s>=n) {
printf (
"%d card(s)\n" ,i
-1 );
break ; } }
scanf (
"%lf" ,&n); }
return 0 ; }
算法訓練 Hanoi問題
問題描述 如果將課本上的Hanoi塔問題稍做修改:仍然是給定N只盤子,3根柱子,但是允許每次最多移動相鄰的M只盤子(當然移動盤子的數目也可以小于M),最少需要多少次? 例如N=5,M=2時,可以分別將最小的2個盤子、中間的2個盤子以及最大的一個盤子分別看作一個整體,這樣可以轉變為N=3,M=1的情況,共需要移動7次。 輸入格式 輸入數據僅有一行,包括兩個數N和M(0<=M<=N<=8) 輸出格式 僅輸出一個數,表示需要移動的最少次數 樣例輸入 5 2
樣例輸出
7
#include <stdio.h> int main () {
int N,M;
scanf (
"%d%d" ,&N,&M); N=(N+
1 )/M;
printf (
"%d" ,(
1 <<N)
-1 );
return 0 ; }
漢若塔
說明河內之塔(Towers of Hanoi)是法國人M.Claus(Lucas)于1883年從泰國帶至法國的,河內為越戰時北越的首都,即現在的胡志明市;1883年法國數學家 Edouard Lucas曾提及這個故事,據說創世紀時Benares有一座波羅教塔,是由三支鉆石棒(Pag)所支撐,開始時神在第一根棒上放置64個由上至下依由小至大排列的金盤(Disc),并命令僧侶將所有的金盤從第一根石棒移至第三根石棒,且搬運過程中遵守大盤子在小盤子之下的原則,若每日僅搬一個盤子,則當盤子全數搬運完畢之時,此塔將毀損,而也就是世界末日來臨之時。 解法如果柱子標為ABC,要由A搬至C,在只有一個盤子時,就將它直接搬至C,當有兩個盤子,就將B當作輔助柱。如果盤數超過2個,將第三個以下的盤子遮起來,就很簡單了,每次處理兩個盤子,也就是:A->B、A ->C、B->C這三個步驟,而被遮住的部份,其實就是進入程式的遞回處理。事實上,若有n個盤子,則移動完畢所需之次數為2^n - 1,所以當盤數為64時,則所需次數為:264- 1 = 18446744073709551615為5.05390248594782e+16年,也就是約5000世紀,如果對這數字沒什幺概念,就假設每秒鐘搬一個盤子好了,也要約5850億年左右。
#include <stdio.h> void hanoi (int n, char A, char B, char C) {
if (n ==
1 ) {
printf (
"Move sheet %d from %c to %c\n" , n, A, C); }
else { hanoi(n
-1 , A, C, B);
printf (
"Move sheet %d from %c to %c\n" , n, A, C); hanoi(n
-1 , B, A, C); } }
int main () {
int n;
printf (
"請輸入盤數:" );
scanf (
"%d" , &n); hanoi(n,
'A' ,
'B' ,
'C' );
return 0 ; }
算法訓練 蜜蜂飛舞
問題描述 “兩只小蜜蜂呀,飛在花叢中呀……”
話說這天天上飛舞著兩只蜜蜂,它們在跳一種奇怪的舞蹈。用一個空間直角坐標系來描述這個世界,那么這兩只蜜蜂初始坐標分別為(x1,y1,z1),(x2,y2,z2) 。在接下來它們將進行n次飛行,第i次飛行兩只蜜蜂分別按照各自的速度向量飛行ti個單位時間。對于這一現象,瑋瑋已經觀察了很久。他很想知道在蜜蜂飛舞結束時,兩只蜜蜂的距離是多少。現在他就求教于你,請你寫一個程序來幫他計算這個結果。 輸入格式 第一行有且僅有一個整數n,表示兩只蜜蜂將進行n次飛行。
接下來有n行。
第i行有7個用空格分隔開的整數ai,bi,ci,di,ei,fi,ti ,表示第一只蜜蜂單位時間的速度向量為(ai,bi,ci) ,第二只蜜蜂單位時間的速度向量為(di,ei,fi) ,它們飛行的時間為ti 。
最后一行有6個用空格分隔開的整數x1,y1,z1,x2,y2,z2,如題所示表示兩只蜜蜂的初始坐標。 輸出格式 輸出僅包含一行,表示最后兩只蜜蜂之間的距離。保留4位小數位。 樣例輸入 Sample 1 1 1 1 1 1 -1 1 2 3 0 1 2 0 0 Sample 2 3 1 1 1 1 -1 1 2 2 1 2 0 -1 -1 2 2 0 0 -1 1 1 3 3 0 1 2 0 0
樣例輸出
Sample 1 4.2426 Sample 2 15.3948
#include <stdio.h> #include <math.h> int main() {
int n; double x1=
0 ,y1=
0 ,z1=
0 ,x2=
0 ,y2=
0 ,z2=
0 ;
int ai,bi,ci,di,ei,fi,ti;
int i; scanf(
"%d" ,&n);
for (i=
0 ;i<n;i++) { scanf(
"%d%d%d%d%d%d%d" ,&ai,&bi,&ci,&di,&ei,&fi,&ti); x1+=ai*ti; y1+=bi*ti; z1+=ci*ti; x2+=di*ti; y2+=ei*ti; z2+=fi*ti; } scanf(
"%d%d%d%d%d%d" ,&ai,&bi,&ci,&di,&ei,&fi); x1+=ai; y1+=bi; z1+=ci; x2+=di; y2+=ei; z2+=fi;
printf (
"%.4lf" ,
sqrt ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));
return 0 ; }
算法訓練 關聯矩陣
問題描述 有一個n個結點m條邊的有向圖,請輸出他的關聯矩陣。 輸入格式 第一行兩個整數n、m,表示圖中結點和邊的數目。n<=100,m<=1000。 接下來m行,每行兩個整數a、b,表示圖中有(a,b)邊。 注意圖中可能含有重邊,但不會有自環。 輸出格式 輸出該圖的關聯矩陣,注意請勿改變邊和結點的順序。 樣例輸入 5 9 1 2 3 1 1 5 2 5 2 3 2 3 3 2 4 3 5 4 樣例輸出 1 -1 1 0 0 0 0 0 0 -1 0 0 1 1 1 -1 0 0 0 1 0 0 -1 -1 1 -1 0 0 0 0 0 0 0 0 1 -1 0 0 -1 -1 0 0 0 0 1
#include <stdio.h> int main () {
int i, ii,n,m, a[
1000 ][
2 ];
scanf (
"%d%d" , &n, &m);
for ( i =
0 ; i < m; i++)
scanf (
"%d%d" , &a[i][
0 ], &a[i][
1 ]);
for ( i =
1 ; i <=n; i++) {
for (ii =
0 ; ii < m; ii++) {
if (i==a[ii][
0 ]) {
printf (
"1 " ); }
else if (i==a[ii][
1 ]) {
printf (
"-1 " ); }
else {
printf (
"0 " ); } }
printf (
"\n" ); }
return 0 ; }
算法訓練 尋找數組中最大值
問題描述 對于給定整數數組a[],尋找其中最大值,并返回下標。 輸入格式 整數數組a[],數組元素個數小于1等于100。輸出數據分作兩行:第一行只有一個數,表示數組元素個數;第二行為數組的各個元素。 輸出格式 輸出最大值,及其下標 樣例輸入 33 2 1 樣例輸出 3 0
#include <stdio.h> #define MaxSize 100+5 main() {
int a[MaxSize],n;
int i,flag,max;
scanf (
"%d" ,&n);
for (i=
0 ;i<n;i++) {
scanf (
"%d" ,&a[i]);
if (i==
0 ) { max=a[i]; flag=i; }
if (a[i]>max) { max=a[i]; flag=i; } }
printf (
"%d %d\n" ,max,flag);
return 0 ; }
算法訓練 數組查找及替換
問題描述 給定某整數數組和某一整數b。要求刪除數組中可以被b整除的所有元素,同時將該數組各元素按從小到大排序。如果數組元素數值在A到Z的ASCII之間,替換為對應字母。元素個數不超過100,b在1至100之間。 輸入格式 第一行為數組元素個數和整數b 第二行為數組各個元素 輸出格式 按照要求輸出 樣例輸入 7 2 77 11 66 22 44 33 55
樣例輸出
11 33 55 M
#include <stdio.h> #include <stdlib.h> void del (int a[],int *len,int m) {
int i,j;
for (i=
0 ;i<*len;i++)
if (a[i]%m==
0 ) {
for (j=i;j<*len;j++) a[j]=a[j+
1 ]; (*len)--; i--; } }
int cmp (const void *a,const void *b) {
return *(
int *)a-*(
int *)b; }
int main () {
int a[
101 ]={},i,m,n;
scanf (
"%d%d" ,&n,&m);
for (i=
0 ;i<n;i++)
scanf (
"%d" ,&a[i]); del(a,&n,m); qsort(a,n,
sizeof (a[
0 ]),cmp);
for (i=
0 ;i<n;i++) {
if (a[i]>=
65 &&a[i]<=
90 )
printf (
"%c " ,a[i]);
else printf (
"%d " ,a[i]); }
return 0 ; }
算法訓練 Torry的困惑(基本型)
問題描述 Torry從小喜愛數學。一天,老師告訴他,像2、3、5、7……這樣的數叫做質數。Torry突然想到一個問題,前10、100、1000、10000……個質數的乘積是多少呢?他把這個問題告訴老師。老師愣住了,一時回答不出來。于是Torry求助于會編程的你,請你算出前n個質數的乘積。不過,考慮到你才接觸編程不久,Torry只要你算出這個數模上50000的值。 輸入格式 僅包含一個正整數n,其中n<=100000。 輸出格式 輸出一行,即前n個質數的乘積模50000的值。 樣例輸入 1 樣例輸出 2 思路二:遞歸
#include <stdio.h> int isPrime(
int num) {
int i;
// 此題不牽扯到
1 if (num==
1 ) {
return 0 ; }
for (i=
2 ;i*i<num+
1 ;i++) {
// 能被其區間(
2 ,
sqrt (num+
1 ))整除的數不是質數
if (num%i==
0 ) {
return 0 ; } }
return 1 ; }
int getNextPrime(
int num) {
// 取下一個數 ,直到得出結果
while (++num) {
// 判斷num,如果是質數則返回此值
if (isPrime(num)) {
return num; } }
return 0 ; }
int getResult(
int n) {
int result=
1 ,
next =
2 ;
while (n--) {
//printf (
"result_value:%d\n" ,result);
// 測試結果 //
printf (
"next_value:%d\n" ,
next );
// 測試下一質數 //結果累計 result=result*
next %50000;
// 獲得
next 的下一質數
next =getNextPrime(
next ); }
return result; } main() {
int n; scanf(
"%d" ,&n);
printf (
"%d\n" ,getResult(n));
return 0 ; }
算法訓練 排列問題
問題描述 求一個0~N-1的排列(即每個數只能出現一次),給出限制條件(一張N*N的表,第i行第j列的1或0,表示為j-1這個數不能出現在i-1這個數后面,并保證第i行第i列為0),將這個排列看成一個自然數,求從小到大排序第K個排列。 數據規模和約定 N<=10,K<=500000 輸入格式 第一行為N和K,接下來的N行,每行N個數,0表示不能,1表示能 輸出格式 所求的排列 樣例輸入 3 2 0 1 1 1 0 0 0 1 0
樣例輸出
1 0 2 解釋: 對于N=3的沒有任何限制的情況 第一:0 1 2 第二:0 2 1 第三:1 0 2 第四:1 2 0 第五:2 0 1 第六:2 1 0 根據題目所給的限制條件由于2不能出現在1后面,0不能出現在2后面 第一:0 2 1 第二:1 0 2 第三:2 1 0
#include "iostream" #include "string" #include "stdio.h" #include "ctype.h" #include "algorithm" #include "stack" using namespace std ;
const int N =
101 ;
int a[
11 ];
bool map [
11 ][
11 ];
bool isOk (int n) {
for (
int i=
0 ;i<n
-1 ;i++)
if (
map [ a[i] ][ a[i+
1 ] ] ==
0 ) {
return false ; }
return true ; }
void init () {
for (
int i=
0 ;i<
10 ;i++) a[i]=i; }
int main () {
int n;
int k;
cin >>n>>k;
for (
int i=
0 ;i<n;i++)
for (
int j =
0 ; j < n; j++)
cin >>
map [i][j]; init();
int num=
0 ;
do {
if (isOk(n)) num++;
if (num==k) {
cout <<a[
0 ];
for (
int i=
1 ;i<n;i++)
cout <<
" " <<a[i];
cout <<
endl ;
break ; }
//cout<<endl; }
while (
std ::next_permutation(a,a+n)); }
算法訓練 最小乘積(基本型)
問題描述 給兩組數,各n個。 請調整每組數的排列順序,使得兩組數據相同下標元素對應相乘,然后相加
的和最小。要求程序輸出這個最小值。 例如兩組數分別為:1 3 -5和-2 4 1
那么對應乘積取和的最小值應為: (-5) * 4 + 3 * (-2) + 1 * 1 = -25 輸入格式 第一個行一個數T表示數據組數。后面每組數據,先讀入一個n,接下來兩行
每行n個數,每個數的絕對值小于等于1000。 n<=8,T<=1000 輸出格式 一個數表示答案。 樣例輸入 231 3 -5-2 4 151 2 3 4 51 0 1 0 1 樣例輸出 -256
#include <stdio.h> #define MaxSize 8+5 //數組排序-序列從大到小 void BubbleSort (int num[],int Size) {
int i,j;
int temp;
for (i=Size
-1 ;i>
0 ;i--) {
for (j=
0 ;j<i;j++) {
if (num[j]<num[j+
1 ]) { temp=num[j]; num[j]=num[j+
1 ]; num[j+
1 ]=temp; } } } } main() {
int T,n,i;
int a[MaxSize],b[MaxSize];
scanf (
"%d" ,&T);
while (T--) {
int sum=
0 ;
scanf (
"%d" ,&n);
for (i=
0 ;i<n;i++) {
scanf (
"%d" ,&a[i]); }
for (i=
0 ;i<n;i++) {
scanf (
"%d" ,&b[i]); }
//數組大到小排序 BubbleSort(a,n); BubbleSort(b,n);
for (i=
0 ;i<n;i++) { sum+=a[i]*b[n
-1 -i]; }
printf (
"%d\n" ,sum); }
return 0 ; }
算法訓練 簡單加法(基本型)
問題描述 首先給出簡單加法算式的定義: 如果有一個算式(i)+(i+1)+(i+2),(i>=0),在計算的過程中,沒有任何一個數位出現了進位,則稱其為簡單的加法算式。 例如:i=3時,3+4+5=12,有一個進位,因此3+4+5不是一個簡單的加法算式;又如i=112時,112+113+114=339,沒有在任意數位上產生進位,故112+113+114是一個簡單的加法算式。
問題:給定一個正整數n,問當i大于等于0且小于n時,有多少個算式(i)+(i+1)+(i+2)是簡單加法算式。其中n<10000。 輸入格式 一個整數,表示n 輸出格式 一個整數,表示簡單加法算式的個數 樣例輸入 4
樣例輸出
3
#include <stdio.h> int main (void ) {
int n,i;
int count=
0 ;
int a,b,c,d;
scanf (
"%d" ,&n);
for (i=
0 ;i<n;i++) { d=i%
10 ; c=i/
10 %
10 ; b=i/
100 %
10 ; a=i/
1000 ;
if (a<=
2 &&b<=
2 &&c<=
2 &&d<=
2 ) count++; }
printf (
"%d" ,count);
return 0 ; }
算法訓練 矩陣加法
問題描述 給定兩個N×M的矩陣,計算其和。其中: N和M大于等于1且小于等于100,矩陣元素的絕對值不超過1000。 輸入格式 輸入數據的第一行包含兩個整數N、M,表示需要相加的兩個矩陣的行數和列數。接下來2N行每行包含M個數,其中前N行表示第一個矩陣,后N行表示第二個矩陣。 輸出格式 你的程序需要輸出一個NM的矩陣,表示兩個矩陣相加的結果。注意,輸出中每行的最后不應有多余的空格,否則你的程序有可能被系統認為是Presentation Error 樣例輸入 2 2 1 2 3 4 5 6 7 8
樣例輸出
6 8 10 12
#include <stdio.h> int main (void ) {
static int a[
100 ][
100 ],b[
100 ][
100 ];
int n,m;
int i,j;
scanf (
"%d%d" ,&n,&m);
for (i=
0 ;i<n;i++)
for (j=
0 ;j<m;j++)
scanf (
"%d" ,&a[i][j]);
for (i=
0 ;i<n;i++)
for (j=
0 ;j<m;j++)
scanf (
"%d" ,&b[i][j]);
for (i=
0 ;i<n;i++) {
for (j=
0 ;j<m;j++) { a[i][j]+=b[i][j];
printf (
"%d " ,a[i][j]); }
printf (
"\n" ); }
return 0 ; }
算法訓練 郵票
問題描述 給定一個信封,有N(1≤N≤100)個位置可以貼郵票,每個位置只能貼一張郵票。我們現在有M(M<=100)種不同郵資的郵票,面值為X1,X2….Xm分(Xi是整數,1≤Xi≤255),每種都有N張。
顯然,信封上能貼的郵資最小值是min(X1, X2, …, Xm),最大值是 N*max(X1, X2, …, Xm)。由所有貼法得到的郵資值可形成一個集合(集合中沒有重復數值),要求求出這個集合中是否存在從1到某個值的連續郵資序列,輸出這個序列的最大值。
例如,N=4,M=2,面值分別為4分,1分,于是形成1,2,3,4,5,6,7,8,9,10,12,13,16的序列,而從1開始的連續郵資序列為1,2,3,4,5,6,7,8,9,10,所以連續郵資序列的最大值為10分。 輸入格式 第一行:最多允許粘貼的郵票張數N;第二行:郵票種數M;第三行:空格隔開的M個數字,表示郵票的面值Xi。注意:Xi序列不一定是大小有序的! 輸出格式 從1開始的連續郵資序列的最大值MAX。若不存在從1分開始的序列(即輸入的郵票中沒有1分面額的郵票),則輸出0. 樣例輸入 樣例一: 4 2 4 1 樣例二: 10 5 2 4 6 8 10
樣例輸出
樣例一: 10 樣例二: 0
#include <stdio.h> #include <string.h> int main () {
int N,M,i,Max,zuixiaozhi,t,found;
//N個位置。M種郵資 int youzi[
260 ];
int dp[
26000 ];
scanf (
"%d %d" ,&N,&M);
for (i=
0 ;i<M;i++) {
scanf (
"%d" ,&youzi[i]); }
memset (dp,
0 ,
sizeof (dp)); Max=
0 ;
while (
1 ) { Max++; found=
0 ; zuixiaozhi=
10000000 ;
for (i=
0 ;i<M;i++) { t=Max-youzi[i];
if (t>=
0 &&dp[t]+
1 <zuixiaozhi) { dp[Max]=dp[t]+
1 ; zuixiaozhi=dp[t]+
1 ; found=
1 ; } }
//printf("%d\n",dp[Max]); if (dp[Max]>N||found==
0 ) {
printf (
"%d\n" ,Max
-1 );
break ; } }
return 0 ; }
算法訓練 刪除多余括號
問題描述 從鍵盤輸入一個含有括號的四則運算表達式,要求去掉可能含有的多余的括號,結果要保持原表達式中變量和運算符的相對位置不變,且與原表達式等價,不要求化簡。另外不考慮'+' '-'用作正負號的情況,即輸入表達式不會出現(+a)或(-a)的情形。 輸入格式 表達式字符串,長度不超過255, 并且不含空格字符。表達式中的所有變量都是單個小寫的英文字母, 運算符只有加+減-乘除/等運算符號。 輸出格式 去掉多余括號后的表達式 樣例輸入 樣例一: a+(b+c)-d 樣例二: a+b/(c+d) 樣例三: (ab)+c/d 樣例四: ((a+b)*f)-(i/j)
樣例輸出
樣例一: a+b+c-d 樣例二: a+b/(c+d) 樣例三: ab+c/d 樣例四: (a+b)f-i/j
#include <stdio.h> int q(char *ch) {
int i=
0 ,z=
0 ; ch[i] =
'#' ;
while (ch[i] !=
')' ||z!=
0 ) {
if (ch[i]==
'(' ) { z++; }
if (ch[i]==
')' ) { z--; } i++; } ch[i] =
'#' ;
return i; }
int f(char *ch, char a) {
int i =
0 ,jj=
0 ;
if (a ==
'+' ) {
while (ch[i] !=
')' ) {
if (ch[i+
1 ] ==
'(' )
if (f(&ch[i], ch[i -
1 ]) ==
0 ) i +=
q(&ch[i]) ;
else {
while (ch[i] !=
')' ) { i++; } } i++; }
if (ch[i +
1 ] ==
'*' || ch[i +
1 ] ==
'/' ) {
return 1 ; }
else {
return 0 ; } }
if (a ==
'-' ) {
while (ch[i] !=
')' ) {
if (ch[i] ==
'(' )
if (f(&ch[i+
1 ], ch[i -
1 ]) ==
0 ) i +=
q(&ch[i]) ;
else {
while (ch[i] !=
')' ) { i++; } }
if (ch[i] ==
'+' || ch[i] ==
'-' )
return 1 ; i++; }
if (ch[i +
1 ] ==
'*' || ch[i +
1 ] ==
'/' ) {
return 1 ; }
else {
return 0 ; } }
if (a ==
'*' ) {
while (ch[i] !=
')' ) {
if (ch[i] ==
'(' )
if (f(&ch[i+
1 ], ch[i -
1 ]) ==
0 )
q(&ch[i]) ;
else {
while (ch[i] !=
')' ) { i++; } }
if (ch[i] ==
'+' || ch[i] ==
'-' )
return 1 ; i++; }
return 0 ; }
if (a ==
'/' ) {
while (ch[i] !=
')' ) {
if (ch[i] ==
'(' )
if (f(&ch[i+
1 ], ch[i -
1 ]) ==
0 )
q(&ch[i]) ;
else {
while (ch[i] !=
')' ) { i++; } }
if (ch[i] ==
'+' || ch[i] ==
'-' || ch[i] ==
'/' || ch[i] ==
'*' )
return 1 ; i++; } }
while (ch[i] !=
')' ) {
if (ch[i] ==
'(' )
if (f(&ch[i+
1 ], ch[i -
1 ]) ==
0 ) i +=
q(&ch[i]) ;
else {
while (ch[i] !=
')' ) { i++; } }
if (ch[i] ==
'+' || ch[i] ==
'-' ) jj=
1 ; i++; }
if ((ch[i +
1 ] ==
'*' || ch[i +
1 ] ==
'/' )&&jj==
1 ) {
return 1 ; }
else {
return 0 ; } } void g(char *a) {
int i =
0 ;
while (a[i]!=
'\0' ) {
if (a[i] ==
'(' )
if (f(&a[i +
1 ], a[i -
1 ]) ==
0 )
q(&a[i]) ;
else {
while (a[i] !=
')' ) { i++; } } i++; } }
int main() {
int l =
0 , i =
0 ; char ch[
100 ]; scanf(
"%s" , ch); g(ch);
while (ch[i]!=
'\0' ) {
if (ch[i]!=
'#' ) {
printf (
"%c" , ch[i]); } i++; }
return 0 ; }
算法訓練 字串逆序
問題描述 給定一個字符串,將這個串的所有字母逆序后輸出。 輸入格式 輸入包含一個字符串,長度不超過100,字符串中不含空格。 輸出格式 輸出包含一個字符串,為上面字符串的逆序。 樣例輸入 tsinsen 樣例輸出 nesnist
#include <stdio.h> #include <string.h> int main () {
char str[
100 ];
int len;
scanf (
"%s" ,str); len=
strlen (str)
-1 ;
for (;len>=
0 ;len--)
printf (
"%c" ,str[len]);
return 0 ; }
#include <iostream> using namespace std ;
// 交換兩個整數 void Swap (int *a, int *b) {
int temp=*a; *a=*b; *b=temp; }
int main () {
int a, b;
cin >> a >> b; Swap(&a, &b);
cout << a <<
" " << b;
return 0 ; }
算法訓練 矩陣乘方
問題描述 給定一個矩陣A,一個非負整數b和一個正整數m,求A的b次方除m的余數。 其中一個nxn的矩陣除m的余數得到的仍是一個nxn的矩陣,這個矩陣的每一個元素是原矩陣對應位置上的數除m的余數。 要計算這個問題,可以將A連乘b次,每次都對m求余,但這種方法特別慢,當b較大時無法使用。下面給出一種較快的算法(用A^b表示A的b次方): 若b=0,則A^b%m=I%m。其中I表示單位矩陣。 若b為偶數,則A^b%m=(A^(b/2)%m)^2%m,即先把A乘b/2次方對m求余,然后再平方后對m求余。 若b為奇數,則A^b%m=(A^(b-1)%m)*a%m,即先求A乘b-1次方對m求余,然后再乘A后對m求余。 這種方法速度較快,請使用這種方法計算A^b%m,其中A是一個2x2的矩陣,m不大于10000。 輸入格式 輸入第一行包含兩個整數b, m,第二行和第三行每行兩個整數,為矩陣A。 輸出格式 輸出兩行,每行兩個整數,表示A^b%m的值。 樣例輸入 2 2 1 1 0 1 樣例輸出 1 0 0 1
#include <stdio.h> int b, m;
int a[
2 ][
2 ], ans[
2 ][
2 ], temp[
2 ][
2 ] = {
1 ,
1 ,
1 ,
1 };
void play () {
int cnt, cnt2;
for (cnt =
0 ; cnt <
2 ; ++cnt) {
for (cnt2 =
0 ; cnt2 <
2 ; ++cnt2) {
printf (
"%d " , ans[cnt][cnt2]); }
printf (
"\n" ); } }
void cp (int arr1[][2 ], int arr2[][2 ]) {
int cnt, cnt2;
for (cnt =
0 ; cnt <
2 ;++cnt)
for (cnt2 =
0 ; cnt2 <
2 ; ++cnt2) arr1[cnt][cnt2] = arr2[cnt][cnt2]; }
void mod (int arr[][2 ]) {
int cnt, cnt2;
for (cnt =
0 ; cnt <
2 ; ++cnt)
for (cnt2 =
0 ; cnt2 <
2 ; ++cnt2) arr[cnt][cnt2] %= m; }
void fun2 (int a[][2 ], int b[][2 ]) {
int cnt, cnt2; temp[
0 ][
0 ] = a[
0 ][
0 ]*b[
0 ][
0 ]+a[
0 ][
1 ]*b[
1 ][
0 ]; temp[
0 ][
1 ] = a[
0 ][
0 ]*b[
0 ][
1 ]+a[
0 ][
1 ]*b[
1 ][
1 ]; temp[
1 ][
0 ] = a[
1 ][
0 ]*b[
0 ][
0 ]+a[
1 ][
1 ]*b[
1 ][
0 ]; temp[
1 ][
1 ] = a[
1 ][
0 ]*b[
0 ][
1 ]+a[
1 ][
1 ]*b[
1 ][
1 ]; }
void fun (int arr[][2 ], int k) {
int cnt;
if (k ==
0 ) { mod(temp); cp(ans, temp);
return ; }
if (k ==
1 ) { mod(ans);
return ; }
if (k ==
2 ) { fun2(a, a); cp(ans, temp);
// printf("2\n"); // play(); mod(ans);
return ; }
if (k%
2 ==
0 ) { fun(arr, k/
2 ); fun2(ans, ans); cp(ans, temp);
//printf("=0\n"); //play(); mod(ans);
return ; }
if (k%
2 !=
0 ) { fun(arr, k
-1 ); fun2(ans, arr); cp(ans, temp);
//printf("!=0\n"); // play(); mod(ans);
return ; } }
int main () {
int cnt, cnt2;
scanf (
"%d%d" , &b, &m);
for (cnt =
0 ; cnt <
2 ; ++cnt)
for (cnt2 =
0 ; cnt2 <
2 ; ++cnt2) {
scanf (
"%d" , &a[cnt][cnt2]); ans[cnt][cnt2] = a[cnt][cnt2]; } fun(a, b); play();
return 0 ; }
總結
以上是生活随笔 為你收集整理的蓝桥杯练习系统习题-算法训练3 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。