牛客小白月賽1題目題解

點擊查看題目

A-簡單題

/**************************************************************
Data 2018-03-17 19:09:51
Author Ms. Wen

解題思路:考察高等數學I的知識,知道lim(v->無窮)(1+1/v)^v = e
就能輕鬆解出該題。最終公式爲 ans = y*e^x。e^x 可以用函數exp(x)
算出。exp(x) = e^x.數C語言Math庫的數學函數。
*************************************************************/
#include <stdio.h>
#include <math.h>

int main() {
    int x,y,z;
    int t;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d%d",&x,&y,&z);
        double ans = exp(x)*y;
        if(z == 1) printf("%.1lf\n",ans);
        if(z == 2) printf("%.2lf\n",ans);
        if(z == 3) printf("%.3lf\n",ans);
        if(z == 4) printf("%.4lf\n",ans);
        if(z == 5) printf("%.5lf\n",ans);
    }
    return 0;
}

B-簡單題2

/****************************************************
Data 2018-03-17 19:17:05
Author Ms. Wen

解題思路:lnR = 1。則R=e。可以知道該題目讓求.x^e/y
e = exp(1) x^e = pow(x,e),全部用數學函數計算即可。
******************************************************/
#include <stdio.h>
#include <math.h>

int main() {
    int x,y,z,t;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d%d",&x,&y,&z);
        double e = exp(1);
        double ans = pow(x,e)/y;
        if(z == 1) printf("%.1lf\n",ans);
        if(z == 2) printf("%.2lf\n",ans);
        if(z == 3) printf("%.3lf\n",ans);
        if(z == 4) printf("%.4lf\n",ans);
        if(z == 5) printf("%.5lf\n",ans);
    }
    return 0;
}

C-分元宵

/**************************************************************
Data 2018/3/23 17:58
Author Ms. Wen

解題思路:
a種餡,b種皮。共能構成a*b種元宵。考慮一張桌子上的擺放情況,一張桌子上
有d個碗,每個碗都可以放這a*b種元宵,對於一張桌子有(a*b)^d种放法,對於
c張桌子,每張桌子對應(a*b)^d種方法,則總共有(a*b)^(c*d)种放法。
注意當讓取模的數爲1時,答案是0。

變量含義:
a,b,c,d:a種餡,b種皮,c張桌子,每張桌子上d個碗
mod:要取模的數

方法含義:
quickPower:整數快速冪,求n的k次方取模後的值。
**********************************************************************/
#include <stdio.h>
#include <iostream>

using namespace std;

typedef long long LL;
LL a,b,c,d;
int mod;
LL quickPower(LL n,LL k) {
    LL res,ans;
    ans = (LL)1;
    res = n;
    while(k) {
        if(k&1) {
            ans = ans*res%mod;
        }
        res = res*res%mod;
        k = k>>1;
    }
    return ans;
}
int main() {
    while(~scanf("%lld%lld%lld%lld%d",&a,&b,&c,&d,&mod)) {
        if(mod == 1) {
            printf("0\n");
        }
        else {
            a = a%mod;
            b = b%mod;
            printf("%lld\n",quickPower(a*b%mod,c*d));
        }
    }
    return 0;
}

D-多項式乘法

/*****************************************
Data 2018-03-17 19:34:35
Author Ms. Wen

解題思路:(A*X^i) * (B*X^j) = A*B*X^(i+j)
*****************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>

using namespace std;


const int maxn = 1e6;
int A[maxn],B[maxn],C[maxn];
int main() {
    int n,m,x;
    while(~scanf("%d%d",&n,&m)) {
        for(int i = 0; i<=n ; i++) {
            scanf("%d",&x);
            A[i] = x;  //第i項的係數爲x
        }
        for(int i = 0; i <= m; i++) {
            scanf("%d",&x);
            B[i] = x; //第i項的係數爲x
        }
        memset(C,0,sizeof(C));
        for(int i = 0; i <= n; i++) {
            for(int j = 0; j <= m; j++) {
                C[i+j] += A[i]*B[j];
            }
        }
        for(int i = 0; i <= m+n; i++) {
            printf("%d",C[i]);
            if(i != m+n) {
                printf(" ");
            }
        }
        printf("\n");
    }
    return 0;
}

E-圓與三角形

/**************************************************************
Data 2018-03-17 20:03:53
Author Ms. Wen

解題思路:
知道tan(A/2)*tan(B/2)+tan(B/2)*tan(C/2)+tan(A/2)*tan(C/2) = 1
題目直接就解決了,sinA*r,r是定值,讓sinA最大就行,sinA最大爲1.
**************************************************************/
#include <stdio.h>

int main() {
    double r;
    while(~scanf("%lf",&r)) {
        double ans = 1 + 1*r;
        printf("%.2lf\n",ans);
    }
    return 0;
}

F-三視圖

/**************************************************************
Data 2018-03-20 21:04:48
Author Ms. Wen

解題思路:
正視圖和左視圖從大到小固定y,然後把每行的x和z從小到大
對於附視圖,則從小到大固定z,然後每行的x從小到大。
主要還是要區別程序打出符號和自己在紙上的順序是不一樣的,
圖上越左上就要在程序種越早輸出。
**************************************************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
 
using namespace std;
 
const int maxn = 1004;
int zhu[maxn][maxn];  //主視圖
int zuo[maxn][maxn];  //左視圖
int fu[maxn][maxn];   //俯視圖
int X,Y,Z,N;
int main() {
    while(~scanf("%d%d%d%d",&X,&Y,&Z,&N)) {
        int x,y,z;
        memset(zhu,0,sizeof(zhu));
        memset(zuo,0,sizeof(zuo));
        memset(fu,0,sizeof(fu));
        for(int i = 0; i < N; i++) {
            scanf("%d%d%d",&x,&y,&z);
            zhu[y][x] = 1;   //yoz面
            zuo[y][z] = 1;   //yox面
            fu[z][x] = 1;    //zox面
        }
        while(Y>0) {
            for(int i = 1; i <= X; i++) {
                if(zhu[Y][i]) {
                    printf("x");
                }
                else {
                    printf(".");
                }
            }
            printf(" ");
            for(int i = 1; i <= Z; i++) {
                if(zuo[Y][i]) {
                    printf("x");
                }
                else {
                    printf(".");
                }
            }
            printf("\n");
            Y--;
        }
        printf("\n");
        for(int i = 1; i <= Z; i++) {
            for(int j = 1; j <= X; j++) {
                if(fu[i][j]) {
                    printf("x");
                }
                else {
                    printf(".");
                }
            }
            printf("\n");
        }
    }
    return 0;
}

G-あなたの蛙は旅⽴っています

題目的難點在於存圖,將題目給出數據按如下圖所示方式存儲。


/**************************************************************
Data 2018-03-22 15:28
Author Ms. Wen

解題思路:
按如圖方式存儲後。對於除第一行以外的其他行的元素,假如考慮
第i行第j列的元素,可以知道它可以座標爲(i-1,j-1),(i-1,j+1)和(i-2,j)
三個位置得到。
則有公式:Map[i][j] += Max(Map[i-1][j-1],Map[i-1][j+1],Map[i-2][j]
                                
變量含義:
Map:存放題目給出的數據。

方法含義:
Max:求三個數中的最大值並返回。
**************************************************************/
#include <stdio.h>
#include <string.h>

#define inf 0x3f3f3f3f
#define maxn 3500

int Map[maxn][maxn];
void init() {
    for(int i = 0; i < maxn; i++) {
        for(int j = i; j < maxn; j++) {
           Map[i][j] = Map[j][i] = -inf;
        }
    }
}
int Max(int a,int b,int c) {
    if(a<b) {
        a = b;
    }
    if(a<c) {
        a = c;
    }
    return a;
}
int main() {
    int N;
    while(~scanf("%d",&N)) {
        init();  //初始化
        int start = N,i,j;
        //先輸入前N行
        for(i = 1; i <= N; i++) {
            for(j = start; j <= N+i-1; j+=2) {   //第i行從start位置開始填數,每隔一格填一個數
                scanf("%d",&Map[i][j]);
            }
            start--;
        }
        //在輸入N+1 ~ 3*N-3行
        start = 2;
        for(; i <= 3*N-3; i++) {
            for(j = start; j < 2*N; j+=2) {
                scanf("%d",&Map[i][j]);
            }
            if(start == 2) start = 1;
            else start = 2;
        }
        //最後輸入後N行
        start = 1;
        for(; i <= 4*N-3; i++) {
            for(j = start; j <= 2*N-start; j+=2) {
                scanf("%d",&Map[i][j]);
            }
            start++;
        }

        start = N-1;
        for(i = 2; i <= N; i++) {
            for(j = start; j <= N+i-1; j+=2) {
                Map[i][j] += Max(Map[i-1][j-1],Map[i-1][j+1],Map[i-2][j]);
            }
            start--;
        }
        start = 2;
        for(; i <= 3*N-3; i++) {
            for(j = start; j < 2*N; j+=2) {
                 Map[i][j] += Max(Map[i-1][j-1],Map[i-1][j+1],Map[i-2][j]);
            }
            if(start == 2) start = 1;
            else start = 2;
        }
        start = 1;
        for(; i <= 4*N-3; i++) {
            for(j = start; j <= 2*N-start; j+=2) {
                 Map[i][j] += Max(Map[i-1][j-1],Map[i-1][j+1],Map[i-2][j]);
            }
            start++;
        }
        printf("%d\n",Map[4*N-3][N]);
    }
    return 0;
}

H-寫真がとどいています

該題題目未給出所有音符對應的字符,需要自己百度普通五線譜。


/**
Data 2018/3/22 17:12
Author Ms. Wen

解題思路:給出出現圈的行對應的字符表。然後每次掃描一列,
只要找到圓圈,變輸出表中對應的字符。否則最後輸出豎線。

變量含義:
music: 存放樂譜
match: match[i]存放第i行出現的圓圈,對應什麼樣的字符。
**/
#include <iostream>
#include <stdio.h>

using namespace std;

const int maxn = 5010;

char music[15][maxn];
char match[]= {' ','F','E','D','C','B','A','G','F','E'};
int main() {
    int n,i,j;
    while(~scanf("%d ",&n)) {
       for(i = 1; i <= 9; i++) {
            scanf("%s",music[i]);
       }
       //一列一列看
       for(i = 0; i < n; i++) {
            for(j = 1; j <= 9; j++) {
                if(music[j][i] == 'o') {
                    printf("%c",match[j]);
                    break;
                }
            }
            if(j == 10 ) printf("|");
       }
       printf("\n");
    }
    return 0;
}

I-あなたの蛙が帰っています

/*************************************************************
Data 2018/3/23 17:04
Author Ms. Wen

解題思路:今天百度了一下才知道考察卡特蘭數。對於n個數的序列,
其出戰方案數多少種,設爲H(n)。如果序列中第k個數是最後一個出
棧的,則k進棧前,其前(k-1)個元素均已出棧,前(k-1)個元素出
棧的序列有H(k-1)種,第k個數出棧前,其後(n-k)個元素均已出棧,
它們的出棧方案數有H(n-k)種。則第k個元素爲最後一個出棧元素對應
的出棧方案數爲H(k-1)*H(n-k),k又可以取遍1~n,所以可得。
H(n) = H(0)*H(n-1)+H(1)*H(n-2)*...H(n-1)*H(1)*H(n-1)*H(0);
題目要求第一個進棧的元素,不能第一個出,則在H(n)種方案中,
只有A1進A1出和剩餘n-1個元素入棧出棧的情況組合是不符合要求的。
則答案就是H(n)-H(n-1).
H(n)還有這種表方法:H(n) = C(2*n,n)/(n+1);
由於該題目牽涉到除法,所以還需要求乘法逆元,題目給出的模是素數,
則可以用小費馬定理求乘法逆元。

變量含義:
fac:fac[i]爲i的階乘取模後的值

方法含義:
calFac:計算fac數組
quickPower:整數快速冪求n的k次方
CatalanNumber:計算卡特蘭數
*****************************************************************/
#include <iostream>
#include <stdio.h>

using namespace std;

const int maxn = 1e6+10;
const long long mod = 998244353;
long long fac[maxn];
void calFac() {
    fac[0] = (long long)1;
    fac[1] = (long long)1;
    for(int i = 2; i < maxn; i++) {
        fac[i] = fac[i-1]*i%mod;
    }
}
long long quickPower(long long n,long long k) {
    long long res,ans;
    res = n;
    ans = (long long)1;
    while(k) {
        if(k&1) {
            ans = ans*res%mod;
        }
        res = res*res%mod;
        k = k>>1;
    }
    return ans;
}
long long CatalanNumber(int n) {
    long long tmp1 = quickPower(fac[n]*fac[n]%mod,mod-2);
    long long tmp2 = quickPower((n+1)%mod,mod-2);
    return fac[2*n]*tmp1%mod*tmp2%mod;
}

int main() {
    calFac();
    int n,t,Case=0;
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        long long ans = (CatalanNumber(n) - CatalanNumber(n-1) + mod)%mod;
        printf("Case #%d: %lld\n",++Case,ans);
    }
    return 0;
}

J-おみやげをまらいました

/*****************************
Data 2018-03-17 20:11:17
Author Ms. Wen
*********************************/
#include <iostream>
#include <stdio.h>
#include <map>
#include <string>

using namespace std;

map<string,string>mp;
int main() {
    mp.clear();
    string s1,s2;
    for(int i = 0; i < 3; i++) {
        cin>>s1>>s2;
        mp[s2] = s1;
    }
    int m;
    scanf("%d ",&m);
    while(m--) {
        getline(cin,s1);
        if(mp[s1] == "") {
            cout<<"Fake"<<endl;
        }
        else {
            cout<<mp[s1]<<endl;
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章