藍橋杯------歷屆真題

《1》核桃的數量  

問題描述

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

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

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

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

輸入格式
輸入包含三個正整數a, b, c,表示每一個組正在加班的人數,用空格分開(a,b,c<30)
輸出格式
輸出一個正整數,表示每袋核桃的數量。
樣例輸入1
2 4 5
樣例輸出1
20
樣例輸入2
3 1 1
樣例輸出2
3
 題目解析
  其實題目就是要求a,b,c的最小公倍數。
參考代碼
複製代碼
#include<stdio.h>

int f(int a,int b)
{
    int i,t;
    if(b>a)
    {
        t=a;
        a=b;
        b=t;
    }
    for(i=a;;i=i+a)
    {
        if(i%a==0&&i%b==0)break;
    }
    return i;
}

int main()
{
    int a,b,c,r;
    
    scanf("%d%d%d",&a,&b,&c);
    
    r=f(a,b);
    r=f(r,c);
    
    printf("%d\n",r);
    
    return 0;
}
複製代碼

 

《2》打印十字圖  

問題描述

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

..
 
 
 
.......................
..
 
$.$.
.....................
$.$.
$.$.
..
................
...
$.$.$.$.
..................
.....
 
...................
...
$.$.$.$.
.....................
$.$.
$.$.
..
...................
$.$.
 
$.$.
.......................
 
 
 
..

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

輸入格式
一個正整數 n (n<30) 表示要求打印圖形的層數。
輸出格式
對應包圍層數的該標誌。
樣例輸入1
1
樣例輸出1
..
 
...............
.$..$.
.........
..
 
..........
$.$.$.$.
...............
 
..
樣例輸入2
3
樣例輸出2
..
 
 
 
.......................
..
 
$.$.
.....................
$.$.
$.$.
..
................
...
$.$.$.$.
..................
.....
 
...................
...
$.$.$.$.
.....................
$.$.
$.$.
..
...................
$.$.
 
$.$.
.......................
 
 
 
..
提示
請仔細觀察樣例,尤爲要注意句點的數量和輸出位置。
參考代碼
複製代碼
#include<stdio.h>

char a[10000][10000];

int main()
{
    int n,i,j,k,b,r,c,d,t,m;
    scanf("%d",&n);
    
    int row=9+(n-1)*4,cll=row,mid=row/2+1;
    k=n-1;
    for(i=1;i<=row/2;k--)
    {
        m=5+4*k;
        b=(row-m)/2;
    //    if(i%2==1)
    //    {
            a[i][mid]='$';
            for(r=mid+1;r<=row-b;r++)
            {
                a[i][r]=a[i][row-r+1]='$';
            }
            if(b==2)
            {
                a[i][r]=a[i][row-r+1]='.';r++;
                a[i][r]=a[i][row-r+1]='.';r++;
            }
            else
            {
                a[i][r]=a[i][row-r+1]='.';r++;t=r+2;
                for(;r<=t;r++)a[i][r]=a[i][row-r+1]='$';
                for(;r<=row;)
                {
                    a[i][r]=a[i][row-r+1]='.';r++;
                    a[i][r]=a[i][row-r+1]='$';r++;
                }
            }
            i++;
    //    }
    //    else
    //    {
            c=m-2;d=(cll-c)/2;
            if(m==1)
            {
                a[i][mid]='$';r=mid+1;
            }
            else
            {
                a[i][mid]='.';
                for(r=mid+1;r<=row-d;r++)    a[i][r]=a[i][row-r+1]='.';
                a[i][r]=a[i][row-r+1]='$';r++;
            }
            //if(d-1==2)
        //    {
                a[i][r]=a[i][row-r+1]='.';r++;
                a[i][r]=a[i][row-r+1]='.';r++;
        //    }
            
            for(;r<=row;)
            {
                a[i][r]=a[i][row-r+1]='.';r++;
                a[i][r]=a[i][row-r+1]='$';r++;
            }
            
    //    }
    i++;
    }
    
    a[i][mid]='$';
    for(r=mid+1;r<=mid+2;r++)a[i][r]=a[i][row-r+1]='$';
    for(;r<=row;)
    {
        a[i][r]=a[i][row-r+1]='.';r++;
        a[i][r]=a[i][row-r+1]='$';r++;
    }
    
    
    for(i=1;i<=row/2+1;i++)
    {
        for(j=1;j<=cll;j++)
        {
            printf("%c",a[i][j]);
        }
        printf("\n");
    }
    
    for(i=row/2;i>0;i--)
    {
        for(j=1;j<=cll;j++)
        {
            printf("%c",a[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}
複製代碼

 

《3》 帶分數  

問題描述

100 能夠表示爲帶分數的形式:100 = 3 + 69258 / 714。設計

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

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

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

輸入格式

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

輸出格式

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

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

樣例輸入1
100
樣例輸出1
11
樣例輸入2
105
樣例輸出2
6
參考代碼
複製代碼
/*
問題描述
    100 能夠表示爲帶分數的形式:100 = 3 + 69258 / 714。
    還能夠表示爲:100 = 82 + 3546 / 197。
    注意特徵:帶分數中,數字1~9分別出現且只出現一次(不包含0)。
    相似這樣的帶分數,100 有 11 種表示法。
輸入格式
    從標準輸入讀入一個正整數N (N<1000*1000)
輸出格式
    程序輸出該數字用數碼1~9不重複不遺漏地組成帶分數表示的所有種數。
    注意:不要求輸出每一個表示,只統計有多少表示法!
樣例輸入1
100
樣例輸出1
11
樣例輸入2
105
樣例輸出2
6
*/

#include<stdio.h>
#include<string.h>
#include<math.h>

#define M 9

int back[M+1],flag[M+1],sum;

//求常數項的標誌 int f1(int a) { int i,j=0; memset(flag,0,sizeof(flag)); while(a) { j++; i=a%10; if(i==0 || flag[i]==1)return 0; else flag[i]=1; a/=10; } return j; }
//求分子或分母是否符合要求 int f2(int a) { memcpy(back,flag,sizeof(flag)); int i,j=0; while(a) { j++; i=a%10; if(i==0 || back[i]==1)return 0; else back[i]=1; a/=10; } return j; }
//求分子a和分母b是否知足要求 int f3(int a,int b) { memcpy(back,flag,sizeof(flag)); int i; while(a) { i=a%10; if(i==0 || back[i]==1)return 0; else back[i]=1; a/=10; } while(b) { i=b%10; if(i==0 || back[i]==1)return 0; else back[i]=1; b/=10; } for(i=1;i<=M;i++) { if(back[i]==0)return 0; } return 1; } int main() { int N,i,j,k,nz,nfz,nfm,a,b,fz,fm,fzup; scanf("%d",&N); sum=0; for(i=1;i<=N;i++) { if((nz=f1(i))==0)continue; fzup=pow(10,M-nz+1)-1; a=N-i;b=1; for(k=2;k<=98765&&a*k<fzup;k++) { if((nfz=f2(k))==0)continue; if(f3(a*k,k)==1) { sum++; // printf("zshu=%d fz=%d fm=%d\n",i,a*k,k); } } } printf("%d\n",sum); return 0; }
複製代碼

《4》剪格子  

問題描述

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

+--*--+--+
|10* 1|52|
+--****--+
|20|30* 1|
*******--+
| 1| 2| 3|
+--+--+--+

咱們沿着圖中的星號線剪開,獲得兩個部分,每一個部分的數字和都是60。

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

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

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

輸入格式

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

表示表格的寬度和高度。

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

輸出格式
輸出一個整數,表示在全部解中,包含左上角的分割區可能包含的最小的格子數目。
樣例輸入1
3 3
10 1 52
20 30 1
1 2 3
樣例輸出1
3
樣例輸入2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
樣例輸出2
10
題目分析
  顯然這裏要用到搜索算法,而這樣的算法經常藉助於方向數組來完成
參考代碼
複製代碼
#include<stdio.h>
#include<string.h>

int xy[][2]={{1,0},{0,1},{-1,0},{0,-1}};//下一步方向{x,y} 
int a[11][11],vis[11][11],sum,m,n;//m列n行 

//檢查{x,y}是否可行 
int chack(int x,int y,int num)
{
    if(x<1 ||x>n || y<1 || y>m)
        return 0;
    if((num+a[x][y])>sum)
        return 0;
    if(vis[x][y])
        return 0;
    return 1;
}


int f1(int x,int y,int num)//遍歷 
{
    if(num==sum)return 1;
    int i,res=0,xn,yn;
    for(i=0;i<4;i++)//嘗試四個方向
    {
        xn=x+xy[i][0];
        yn=y+xy[i][1];
        if(chack(xn,yn,num))
        {
            vis[xn][yn]=1;
            int res=f1(xn,yn,num+a[xn][yn]);
            if(res>0)return res+1;
            vis[xn][yn]=0;
        }
    }
    return 0;
}


int main()
{
    scanf("%d%d",&m,&n);
    int i,j;
    sum = 0;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            scanf("%d",&a[i][j]);
            sum+=a[i][j];
        }
    }
    
    if(sum%2==1) printf("0\n");//若是全部格子的和不能分紅相等的半 
    else
    {
        sum/=2;
        memset(vis,0,sizeof(vis));//從左上角開始遍歷 
        vis[1][1]=1;
        printf("%d\n",f1(1,1,a[1][1]));
    }
    
    return 0;
}
複製代碼

 

《5》 翻硬幣  

問題描述

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

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

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

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

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

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

輸入格式

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

輸出格式

一個整數,表示最小操做步數。

樣例輸入1
**********
o****o****
樣例輸出1
5
樣例輸入2
*o**o***o***
*o***o**o***
樣例輸出2
1
思路
檢查兩個字符串,若對應位置相等則不翻轉,否在將該位置的硬幣和下一個相鄰位置硬幣同時作翻轉,依次檢查直到檢查完畢。

總結:注意:

在測試代碼的時候用本地文件存儲數據而後讀取數據是較快的測試方法,可是要注意再提交代碼的時候要將相應的對文件進行操做的代碼註釋掉
否在提交代碼會因找不到相應的文件而報錯

參考代碼

複製代碼
#include<stdio.h>
#include<string.h>
#define M 10100

char ch1[M],ch2[M]; 
int main()
{
    int i,j,len,step;
    FILE *f;
//    f=fopen("testnum.txt","r+");
//    fscanf(f,"%s\n",&ch1);
    scanf("%s\n",&ch1);
    //getchar();
//    fscanf(f,"%s",&ch2);
    scanf("%s",&ch2);
    
    len=strlen(ch1);
    step=0;
    char c;
    for(i=0;i<len;i++)
    {
        if(ch1[i]==ch2[i])continue;
        if(ch1[i]=='*')ch1[i]='o';
        else ch1[i]='*';
        if(ch1[i+1]=='*')ch1[i+1]='o';
        else ch1[i+1]='*';
        step++;
    }
    
    printf("%d\n",step);
//    fclose(f);
    return 0;
}
相關文章
相關標籤/搜索