1. 程式人生 > >演算法-藍橋杯習題(3-5)

演算法-藍橋杯習題(3-5)

藍橋杯習題

    藍橋杯練習系統習題加答案,總共分為6部分,90%習題使用C語言解答,部分使用C++或者Java。大部分習題為搜尋參考或者別人提供所得,不足之處在所難免,懇請批評指正(預計200多題,習題僅供學習交流)

目錄

藍橋杯練習系統評測資料

演算法訓練(PartE-11題)


/*
演算法訓練 輸出米字形

根據輸入的正整數n (1  米字形由一個(2n-1)*(2n-1)的矩陣組成,矩陣包含從大寫A開始的n個字母
  例如:n=3時,包含A,B,C;n=4時,包含A,B,C,D。
  矩陣的正中間為n個字母中字典序最大的那個,從這個字母開始,沿著西北、正北、東北、正西、正東、西南、正南、東南八個方向各有一條由大寫字母組成的直線。並且直線上的字母按字典序依次減小,直到大寫字母A。
  矩陣的其它位置用英文句號.填充。

  樣例輸入一
  3

  樣例輸出一
  A.A.A
  .BBB.
  ABCBA
  .BBB.
  A.A.A

  樣例輸入二
  4

  樣例輸出二
  A..A..A
  .B.B.B.
  ..CCC..
  ABCDCBA
  ..CCC..
  .B.B.B.
  A..A..A
*/
#include <stdio.h>
int main()
{
    int n,i,j,k,t;
    scanf("%d",&n);
    char a[2*n-1][2*n-1];
    for(i=0;i<2*n-1;i++)
    for(j=0;j<2*n-1;j++)
    a[i][j]=0;
    k=n;
    
    for(i=0;i<n-1;i++) //行數 
    {
        k--;  //k為字元間隔 
        t=i;
        for(j=1;j<=3;j++)
        {
          a[i][t]='A'+i;
          t+=k;
        }
    }
    for(i=0;i<n;i++)    //中間一行 
    {
        a[n-1][i]='A'+i;
        a[n-1][2*n-2-i]='A'+i;
    }
    for(i=0;i<=n-2;i++)   //填補句號 
    for(j=0;j<2*n-1;j++)
    {
        if(a[i][j]==0)
        a[i][j]='.';
    }
    
    for(i=0;i<=n-2;i++)    //翻轉 
    for(j=0;j<2*n-1;j++)
    a[2*n-2-i][j]=a[i][j];
    
    for(i=0;i<2*n-1;i++)
    {
    for(j=0;j<2*n-1;j++)
    printf("%c",a[i][j]);
    printf("\n"); 
    }

    
    return 0;
}

/*
演算法訓練 階乘

問題描述
  一個整數n的階乘可以寫成n!,它表示從1到n這n個整數的乘積。階乘的增長速度非常快,例如,13!就已經比較大了,已經無法存放在一個整型變數中;而35!就更大了,它已經無法存放在一個浮點型變數中。因此,當n比較大時,去計算n!是非常困難的。幸運的是,在本題中,我們的任務不是去計算n!,而是去計算n!最右邊的那個非0的數字是多少。例如,5! = 1*2*3*4*5 = 120,因此5!最右邊的那個非0的數字是2。再如:7! = 5040,因此7!最右邊的那個非0的數字是4。請編寫一個程式,輸入一個整數n(n<=100),然後輸出n! 最右邊的那個非0的數字是多少。
  輸入格式:輸入只有一個整數n。
  輸出格式:輸出只有一個整數,即n! 最右邊的那個非0的數字。
  輸入輸出樣例
樣例輸入
6
樣例輸出
2
*/
#include<stdio.h>

int main(void)
{
    int n;
    int i;
    int sum=1;
    scanf("%d",&n);

    for(i=n;i>=1;i--)
    {
        sum = sum*i;
        while(sum%10==0)
            sum=sum/10;
        if(sum/100>0)
            sum=sum%100;
    }

    printf("%d",sum%10);
    
    return 0;
}

/*
演算法訓練 進位制轉換

問題描述
  編寫一個程式,輸入一個二進位制的字串(長度不超過32),然後計算出相應的十進位制整數,並把它打印出來。
  輸入格式:輸入為一個字串,每個字元都是’0’或’1’,字串的長度不超過32。
  輸出格式:輸出一個整數。
  輸入輸出樣例
樣例輸入
1101
樣例輸出
13
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#define MaxSize 32

void print2Return10(char str[])
{
    long long int num=0;
    int lenth=strlen(str),i;
    
    for(i=0;i<lenth;i++)
    {
        if(str[i]!='0')
        {
            num+=pow(2,lenth-i-1);
        }
    }
    
    printf("%lld\n",num);
    
    return ;
}

main()
{
    char str[MaxSize];
    
    gets(str);
    print2Return10(str);
    
    return 0;
}

/*
演算法訓練 字串統計

問題描述
  給定一個長度為n的字串S,還有一個數字L,統計長度大於等於L的出現次數最多的子串(不同的出現可以相交),如果有多個,輸出最長的,如果仍然有多個,輸出第一次出現最早的。
輸入格式
  第一行一個數字L。
  第二行是字串S。
  L大於0,且不超過S的長度。
輸出格式
  一行,題目要求的字串。

  輸入樣例1:
  4
  bbaabbaaaaa

  輸出樣例1:
  bbaa

  輸入樣例2:
  2
  bbaabbaaaaa

  輸出樣例2:
  aa
資料規模和約定
  n<=60
  S中所有字元都是小寫英文字母。

  提示
  列舉所有可能的子串,統計出現次數,找出符合條件的那個
*/
#include<stdio.h>
#include<string.h>
char b[60][60];
int c[60];
int main()
{
    int l,i1,max=1,now=0,maxn=1,i2,weizhi=0,i3,i4,weizhi1,changdu1=-1;
    
    char a[10000];
    scanf("%d",&l);
    getchar();
    gets(a);
    int n=strlen(a);
    
    for(i1=n;i1>=l;i1--)//長度 
    {
        weizhi=0;
         for(i3=0;i3<n-i1;i3++)
                c[i3]=0;
        for(i2=0;i2<n;i2++)//開始位置 
        {
            if(i2+i1>n) 
              break;
            int ok=1;      
           

            for(i3=0;i3<weizhi;i3++)//b的位置 
            {     int ko=1;
                  for(i4=0;i4<i1;i4++)    
                   {  
                         if(b[i3][i4]!=a[i2+i4])
                             ko=0;
                             
                      }
                      if(ko)
                        {  ok=0;
                           c[i3]++;
                        if(c[i3]>max)
                           {max=c[i3];
                            changdu1=i1;
                            weizhi1=i2;
                           }
                        break;
                     }
            
            }
            
            if(ok)
            {
                for(i4=0;i4<i1;i4++)
                {
                    b[weizhi][i4]=a[i2+i4];
                }
                c[weizhi]=1;
                weizhi++;
            }
            
            
        }
        
    
        
    }

    for(i1=weizhi1;i1<weizhi1+changdu1;i1++)
      printf("%c",a[i1]);
      printf("\n");
    return 0;
}

/*
演算法訓練 字元刪除

問題描述
  編寫一個程式,先輸入一個字串str(長度不超過20),再輸入單獨的一個字元ch,然後程式會把字串str當中出現的所有的ch字元都刪掉,從而得到一個新的字串str2,然後把這個字串打印出來。
  輸入格式:輸入有兩行,第一行是一個字串(內部沒有空格),第二行是一個字元。
  輸出格式:經過處理以後的字串。
  輸入輸出樣例
樣例輸入
123-45-678
-
樣例輸出
12345678
*/
#include <stdio.h>
#include <string.h>
#define MaxSize 20+5

void printResult(char str[],char ch)
{
    int i;
    for(i=0;i<strlen(str);i++)
    {
        if(str[i]!=ch)
        {
            printf("%c",str[i]);
        }
    }
    printf("\n");
}

main()
{
    char ch,str[MaxSize];
    
    //if(scanf("%s %c",str,&ch)!=EOF)
    if(gets(str)!=NULL)
    {
        scanf("%c",&ch);
        printResult(str,ch);
    }
    
    return 0;
}

/*
演算法訓練 反置數

問題描述
  一個整數的“反置數”指的是把該整數的每一位數字的順序顛倒過來所得到的另一個整數。如果一個整數的末尾是以0結尾,那麼在它的反置數當中,這些0就被省略掉了。比如說,1245的反置數是5421,而1200的反置數是21。請編寫一個程式,輸入兩個整數,然後計算這兩個整數的反置數之和sum,然後再把sum的反置數打印出來。要求:由於在本題中需要多次去計算一個整數的反置數,因此必須把這部分程式碼抽象為一個函式的形式。
  輸入格式:輸入只有一行,包括兩個整數,中間用空格隔開。
  輸出格式:輸出只有一行,即相應的結果。
  輸入輸出樣例
樣例輸入
435 754
樣例輸出
199
*/
#include <stdio.h>
#include <math.h>

int getTheNumber(int num)
{
    int number=1,i,j=1,flag=0;
    
    if(!num)
    return 0;
    
    while(num)
    {
        i=num%10;
        if(i||flag)
        {
            if(!flag)
            {
                number=i;
            }
            else
            {
                number=number*10+i;
            }
            flag=1;
        }
        num/=10;
    }
    
    return number;
}

main()
{
    int n,m;
    
    scanf("%d%d",&n,&m);
    
    printf("%d\n",getTheNumber(getTheNumber(n)+getTheNumber(m)));
    
    return 0;
}

/*
演算法訓練 新生舞會

問題描述
  新生舞會開始了。n名新生每人有三個屬性:姓名、學號、性別。其中,姓名用長度不超過20的僅由大小寫字母構成的字串表示,學號用長度不超過10的僅由數字構成的字串表示,性別用一個大寫字元‘F’或‘M’表示。任意兩人的姓名、學號均互不相同。換言之,每個人可被其姓名或學號唯一確定。給出m對兩人的資訊(姓名或學號),判斷他們是否能共舞。兩人能共舞的充要條件為兩人性別相異。
輸入格式
  第一行一個整數n(2<=n<=1000),表示學生人數。接下來的n行每行依次包含一名新生的姓名、學號、性別,分別用一個空格隔開。
  之後的一行是一個整數m(1<=m<=1000),表示詢問的數目。接著的m行每行包含兩個資訊(姓名或學號),保證兩個資訊不屬於同一人,中間用一個空格隔開。
輸出格式
  對於每個詢問輸出一行,如果兩人可以共舞,輸出一個大寫字母‘Y’,否則輸出一個大寫字母‘N’。
樣例輸入
4
John 10 M
Jack 11 M
Kate 20 F
Jim 21 M
3
John 11
20 Jack
Jim Jack
樣例輸出
N
Y
N

提示
可以把名字和學號都當成字串處理。可以按以下流程實現。

#include<iostream>
#include<cstring>
using namespace std;

struct tstudent
{
char name[21];
char num[21];
char sex;
};

void readdata(tstudent student[], int n)
{
輸入N個學生的資訊
}

int findstudent(tstudent student[], int n, char* data)
{
if (data == NULL) return -1;

判斷是否有某個學生的學號或名字等於data,如果有,函式返回該學生在student陣列中的序號,否則返回-1
}

void solve(tstudent student[], int n, int m)
{
char x[21], y[21];
for (int i=0; i<m; i++) {
輸入兩個人的資訊X、Y。通過呼叫findstudent函式判斷這兩個人能否成為舞伴
}
}

int main()
{
int n, m;
tstudent student[1010];

cin>>n;

readdata(student, n);
cin>>m;
solve(student, n, m);
}
*/
#include <stdio.h>
#include <string.h>
#define MaxSize 1000+5

typedef struct
{
    char name[21];
    char num[21];
    char sex;
}tstudent;

void readdata(tstudent student[], int n)
{
    int i;
    //輸入N個學生的資訊
    for(i=0;i<n;i++)
    {
        scanf("%s %s %c",student[i].name,student[i].num,&student[i].sex);
    }
}

int findstudent(tstudent student[], int n, char* data)
{
    int i;
    
    if (data == NULL) 
    {
        return -1;
    }
    //判斷是否有某個學生的學號或名字等於data,如果有,函式返回該學生在student陣列中的序號,否則返回-
    for(i=0;i<n;i++)
    {
        if(!strcmp(data,student[i].name)||!strcmp(data,student[i].num))
        return i;
    }
    
    return -1;
}

void solve(tstudent student[], int n, int m)
{
    char x[21], y[21];
    int i,a,b;
    
    for (i=0; i<m; i++) 
    {
        //輸入兩個人的資訊X、Y。通過呼叫findstudent函式判斷這兩個人能否成為舞伴
        scanf("%s %s",x,y);
        if((a=findstudent(student,n,x))!=-1&&(b=findstudent(student,n,y))!=-1)
        {
            if(student[a].sex!=student[b].sex)
            printf("Y\n");
            else
            printf("N\n");
        }
        else
        {
            printf("N\n");
        }
    }
}

int main()
{
    int n, m;
    tstudent student[MaxSize];
    
    scanf("%d",&n);
    readdata(student, n);
    
    scanf("%d",&m);
    solve(student, n, m);
    
    return ;
}

/*
演算法訓練 Hello World!

描述
  本題定義本學期作業題的輸出格式,請認真閱讀。
  如無特殊說明,開頭無空格,間隔符為1個空格,答案最後必須輸出換行符("\n")。
輸入格式
  無
輸出格式
  Hello World!
*/
#include <stdio.h>

main()
{
    printf("Hello World!\n");
    
    return 0;
}

/*
演算法訓練 數位分離

問題描述
  編寫一個程式,輸入一個1000 以內的正整數,然後把這個整數的每一位數字都分離出來,並逐一地顯示。
  輸入格式:輸入只有一行,即一個1000以內的正整數。
  輸出格式:輸出只有一行,即該整數的每一位數字,之間用空格隔開。
  輸入輸出樣例
樣例輸入
769
樣例輸出
7 6 9
*/
#include <stdio.h>

void getResult(int num)
{
    //出口 
    if(num<10)
    {
        printf("%d ",num);
        return ;
    }
    //遞迴 
    getResult(num/10);
    
    printf("%d ",num%10);
}

main()
{
    int n;
    
    scanf("%d",&n);
    getResult(n);
    printf("\n"); 
    
    return 0;
}

/*
演算法訓練 薪水計算

問題描述
  編寫一個程式,計算員工的週薪。薪水的計算是以小時為單位,如果在一週的時間內,員工工作的時間不超過40 個小時,那麼他/她的總收入等於工作時間乘以每小時的薪水。如果員工工作的時間在40 到50 個小時之間,那麼對於前40 個小時,仍按常規方法計算;而對於剩餘的超額部分,每小時的薪水按1.5 倍計算。如果員工工作的時間超過了50 個小時,那麼對於前40 個小時,仍按常規方法計算;對於40~50 個小時之間的部分,每小時的薪水按1.5 倍計算;而對於超出50 個小時的部分,每小時的薪水按2 倍計算。請編寫一個程式,輸入員工的工作時間和每小時的薪水,然後計算並顯示他/她應該得到的週薪。
  輸入格式:輸入只有一行,包括一個整數和一個實數,分別表示工作時間和每小時薪水。
  輸出格式:輸出只有一個實數,表示週薪,保留小數點後2位。
  輸入輸出樣例
樣例輸入
40 50
樣例輸出
2000.00
*/
#include <stdio.h>

main()
{
    int time;
    float money,sum;
    
    scanf("%d%f",&time,&money);
    if(time<=40)
    {
        sum=time*money;
        printf("%.2f\n",sum);
    }
    else
    {
        time-=40;
        if(time<=10)
        {
            sum=time*money*1.5+40*money;
            printf("%.2f\n",sum);
        }
        else
        {
            time-=10;
            sum=time*money*2+10*money*1.5+40*money;
            printf("%.2f\n",sum);
        }
    }
    
    return 0;
}

/*
演算法訓練 整除問題

問題描述
  編寫一個程式,輸入三個正整數min、max和factor,然後對於min到max之間的每一個整數(包括min和max),如果它能被factor整除,就把它打印出來。
  輸入格式:輸入只有一行,包括三個整數min、max和factor。
  輸出格式:輸出只有一行,包括若干個整數。
  輸入輸出樣例
樣例輸入
1 10 3
樣例輸出
3 6 9
*/
#include <stdio.h>

void getResult(int min,int max,int factor)
{
    int i;
    
    for(i=min;i<=max;i++)
    {
        if(i%factor==0)
        {
            printf("%d ",i);
        }
    }
    printf("\n");
    
    return ;
}

main()
{
    int min,max,factor;
    
    scanf("%d%d%d",&min,&max,&factor);
    getResult(min,max,factor);
    
    return 0;
}

GoToTheNextPart