五一歡樂測試(2018廣西省選題)

關於五一的歡樂測試(爆零測試),其實就是今年的廣西省選題。我覺得是十分歡樂了[笑]

總結:滿分290(其實是300,但10分數據錯了),第一次80分,無奈。第二次發現bug後140,最後又跟一大佬學了第4題,最後210,提高組全班第2……(我是不是太蒻了)


第一題:難度普及–(我這種蒟蒻都AC了)

1.多項式係數計算
【問題描述】
有多項式(A+B)n =C0nAn+C1nAn-1B+C2nAn-2B2+,···,+Cnn-2A2Bn-2+Cnn-1ABn-1+CnnBn,計算其展開的多項式係數爲C0n,C1n,C2n ,· · · ,Cnn-2,Cnn-1,Cnn,,當冪指數n=7時,其展開多項式係數爲:1、7、2 1 、35、35、21、7、1, 請計算7<n≤28時多項式的係數,輸出多項式的展開式。

說明:C0n由於文本問題,0其實是C的上標,n是C的下標

【輸入格式】
輸入文件dxsxs.in 一個整數冪指數 n。
【輸出格式】
輸出文件dxsxs.out ,有2行,第1行輸出冪指數N的值,第二行輸出多項式。
【輸入樣例】
7
【輸出樣例】
N=7
A^7+7A^6B+21A^5B^2+35A^4B^3+35A^3B^4+21A^2B^5+7AB^6+B^7
【數據規模和約定】
50%的數據,滿足7<n≤20;
100%的數據,滿足7<n≤28。

- 思路:這一題乍一看好像很難。其實找C即找係數就是用楊輝三角。

- 圖片如下

楊輝三角

- 然後輸出多項式要注意的是3個點。1:是一個單項式,不輸出+。2:如果指數爲0,不輸出字母。3:如果指數爲1,沒必要顯示出來。

代碼如下嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻
#include <iostream>
#include <string>
using namespace std;

//Statement_common
int n,g1,g2;
int a[1001][1001];
//Statement_fun

int main()
{
    freopen("dxsxs.in","r",stdin);
    freopen("dxsxs.out","w",stdout);

    cin>>n; cout<<"N="<<n<<endl;
    g1=n;   g2=0;//g1,g2控制指數

    //以下四行爲楊輝三角(循環遞推)
    a[0][0]=1;
    for(int i=1;i<=n+1;i++)//循環n+1行
        for(int j=1;j<=i;j++)//每行循環i+1個
            a[i][j]=a[i-1][j]+a[i-1][j-1];

    //以下爲炒雞麻煩的輸出(可能是我太蒻了寫了這麼多)  
    for(int i=1;i<=n+1;i++)
    {
        if(i==1)
        {
            if(a[n+1][i]==1)
            {
                if(g1==0) ;
                else if(g1==1) cout<<"A";
                else cout<<"A^"<<g1;

                if(g2==0) ;
                else if(g2==1) cout<<"B";
                else cout<<"B^"<<g2;
            }
            else
            {
                cout<<a[n+1][i];
                if(g1==0) ;
                else if(g1==1) cout<<"A";
                else cout<<"A^"<<g1;

                if(g2==0) ;
                else if(g2==1) cout<<"B";
                else cout<<"B^"<<g2;
            }
        }
        else
        {
            cout<<"+";
            if(a[n+1][i]==1)
            {
                if(g1==0) ;
                else if(g1==1) cout<<"A";
                else cout<<"A^"<<g1;

                if(g2==0) ;
                else if(g2==1) cout<<"B";
                else cout<<"B^"<<g2;
            }
            else
            {
                cout<<a[n+1][i];
                if(g1==0) ;
                else if(g1==1) cout<<"A";
                else cout<<"A^"<<g1;

                if(g2==0) ;
                else if(g2==1) cout<<"B";
                else cout<<"B^"<<g2;
            }
        }
        g1--;g2++;
    }
    return 0;
}

第二題:評審優秀作品(難度普及–,暴力模擬,AC,無難度)

  1. 評審優秀作品
    【問題描述】
    爲展示泛珠三角大學計算機專業的教學成果,加強各地區計算機教育的交流、促進計算機專業教育質量的提高,滿足社會對計算機應用人才之需求,爲造就計算機英才提供一個良好的交流平臺。每年泛珠三角各省和港澳臺地區的計算機行業學會聯合舉辦大學生計算機作品賽,競賽分初賽和總決賽,初賽在各省區舉行,由各省區選拔出若干優秀作品參加總決賽,總決賽聘請有關從事教學與科研工作的若干名專家對作品進行評審,總決賽評審工作分初評和終評。初評時,只打總分(滿分爲100分),爲減少評委打分偏差過大,對原始分處理成60分至90分範圍內的相對分,處理模型: 設評委P打分的初評最高原始分爲P初max,初評最低原始分爲P初min,作品i的初評原始分爲Pi 初原、初評相對分爲Pi初相 ,則初評時評委P對作品i打分的初評相對分計算公式爲:
    Pi初相 =[(Pi 初原 -P初min )/(P初max-P初min)]×(90-60)+60
    設參賽作品有ZP 項,聘請評審專家PW人蔘加評審工作。例如:有6個作品參賽,聘有5個評審專家參加評審打分,打分表如下:
    作品序號 評委1 評委2 評委3 評委4 評委5
    1 80 90 70 80 50
    2 85 85 80 90 60
    3 90 90 80 100 70
    4 80 95 90 80 75
    5 80 70 70 90 70
    6 90 80 70 90 60

說明:這個表因文本原因,沒有對應好。將就着看吧…

計算作品的最終得分,每個作品先去掉1個最高相對分和1個最低相對分,然後求作品相對分的平均分(取2位小數),並按作品的最終得分降序排出名次。
【輸入格式】
輸入文件 dxszp.in 的第一行,有2個用空格隔開的整數ZP, pw。
接下來的有ZP行,每行有pw個用空格隔開的整數。
【輸出格式】
輸出文件dxszp .out共zp行,每行有3個用空格隔開的整數,依次表示作品的排名、作品最終得分數、作品序號。
【輸入樣例】
6 5
80 90 70 80 50
85 85 80 90 60
90 90 80 100 70
80 95 90 80 75
80 70 70 90 70
90 80 70 90 60
【輸出樣例】
1 86.00 3
2 80.00 4
3 75.00 2
4 73.00 6
5 65.00 5
6 60.00 1
【數據規模和約定】
60%的數據,滿足ZP ≤50 ,pw ≤ 20;
100%的數據,滿足ZP<90 ,pw <35。

- 思路:太簡單了。把題目看懂就可以做了。不想講了。唯一注意的就是處理兩位小數可以這樣寫a=((int)(a*100))/100.0;

- 注:a爲double類型

代碼如下嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

//Statement_common
struct Stu{double xuhao,score;}stu[101];
struct p{double score_max,score_min;}p[101];
int n,m,g;
double sum;
double P[101][101],tmp[101];
//Statement_fun
bool cmp(Stu a,Stu b);

int main()
{
    freopen("dxszp.in","r",stdin);
    freopen("dxszp.out","w",stdout);

    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        stu[i].xuhao=i;
        for(int j=1;j<=m;j++)   cin>>P[i][j];
    }

    for(int j=1;j<=m;j++)
    {
        double t_max=-1,t_min=999999;
        for(int i=1;i<=n;i++)
        {
            t_max=max(t_max,P[i][j]);
            t_min=min(t_min,P[i][j]);
        }
        p[j].score_max=t_max,p[j].score_min=t_min;
    }

    for(int i=1;i<=n;i++)
    {
        g=0,sum=0;
        //P[i][j]:爲第i位作品的第j位評委的評分
        for(int j=1;j<=m;j++)
            //Pi初相 =[(Pi 初原 -P初min )/(P初max -P初min )]×(90-60)+60
            tmp[++g]=((P[i][j]-p[j].score_min)/(p[j].score_max-p[j].score_min))*30+60;
        sort(tmp+1,tmp+1+g);
        for(int k=2;k<=g-1;k++) sum+=tmp[k];
        sum/=(m-2);
        //sum=((int)(sum*100)/100);
        stu[i].score=sum;
    }

    sort(stu+1,stu+1+n,cmp);
    for(int i=1;i<=n;i++)
    {
        printf("%d ",i);
        printf("%.2lf ",stu[i].score);
        cout<<stu[i].xuhao<<endl;
    }
    return 0;
}

bool cmp(Stu a,Stu b)
{
    return a.score>b.score;
}

第三題:除法運算(蒟蒻只得了10分,高精度除法不會寫…)

這題我到現在還不會寫,算法爲高精度除法。有大佬會寫請跟我聯繫,QQ:2789690129(備註:CSDN)

  1. 除法運算
    【問題描述】
    輸入兩個整數a、b,求出a除以b的商和餘數,a、b是小於1000位的非負整數(b<>0)。
    【輸入格式】
    輸入文件 div.in有兩行,第一行爲整數a,第二行爲b。
    【輸出格式】
    輸出文件 div.out有兩行,第一行爲整數a除以b的商,第二行爲餘數。
    【輸入樣例1】
    17
    5
    【輸出樣例1】
    3
    2
    【輸入樣例2】
    10000000000000000000000000000
    99999999999999
    【輸出樣例2】
    100000000000001
    1
    【數據規模和約定】
    50%的數據,滿足10位<a<400位;b<300位;
    100%的數據,滿足10位<a<1000位;b<600位;

- 思路:懵。

代碼如下嘻嘻嘻嘻嘻

#include <iostream>
using namespace std;

int main()
{
    unsigned long long a,b;
    cin>>a>>b;
    cout<<a/b<<endl<<a%b;
    return 0;
{

第四題:合唱隊形(難度普及+/提高-,AC)

  1. 合唱隊形
    【問題描述】
    N位同學站成一排,音樂老師要請其中的(N-K)位同學出列,使得剩下的K位同學不交換位置就能排成合唱隊形。
    合唱隊形是指這樣的一種隊形:設K位同學從左到右依次編號爲1, 2, …, K,他們的身高分別爲T1, T2, …, TK,
    則他們的身高滿足T1 < T2 < … < Ti , Ti > Ti+1 > … > TK (1 <= i <= K)。 你的任務是,已知所有N位同學的身高,
    計算最少需要幾位同學出列,可以使得剩下的同學排成合唱隊形。 同時計算在安排最少同學出列時有多少種方案。
    【輸入格式】
    輸入文件 chorus.in有兩行,第一行是一個整數N(2 <= N <= 1000),表示同學的總數。
    第二行有n個整數,用空格分隔,第i個整數Ti(1300 <= Ti <= 2300)是第i位同學的身高(毫米)。
    【輸出格式】
    輸出文件 chorus.out是一行用空格分隔的二個整數,就是最少需要幾位同學出列、最少同學出列的方案數。
    【輸入樣例】
    8
    1860 1860 1500 2000 1600 1300 1970 2200
    【輸出樣例】
    4 4
    【數據規模和約定】
    60%的數據,滿足10≤n≤300;
    100%的數據,滿足10<n≤1000。

- 思路:首先這題有兩個小問

- 第一個小問 從左往右dp一次,從右邊往左dp一次,找max,老套路

- 第二個小問設置一個數組f[i],表示以i同學爲峯值的最多方案數(同樣也是左掃右掃)

- 狀態如何轉移?(下面爲從左往右掃的代碼示例)

for(int i=1;i<=n;i++)
{
    if(dp_left[i]==1)//如果它的最長上升子序列就他自己,那麼它的方案數就爲1
    {
        f1[i]=1;
        continue;
    }
    else//否則掃他左邊全部的人,如果dp+1等於他的dp,並且高度小於他,就說明能接上他
    for(int j=1;j<=i-1;j++)
        if(dp_left[j]+1==dp_left[i] && a[j]<a[i])
            f1[i]+=f1[j];//那麼方案數+=符合規則的人的方案數
}

代碼如下嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻

#include <iostream>
using namespace std;

//Statement_common
int n,ans=-1,num;
int a[101000],dp_left[101000],dp_right[101000],f1[10100],f2[10100];
//Statement_fun

int main()
{
    freopen("chorus.in","r",stdin);
    freopen("chorus.out","w",stdout);

    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        dp_left[i]=dp_right[i]=1;
    }

    for(int i=2;i<=n;i++)   
        for(int j=1;j<=i-1;j++)
            if(a[i]>a[j])
                dp_left[i]=max(dp_left[i],dp_left[j]+1);
    for(int i=n-1;i>=1;i--)
        for(int j=n;j>=i+1;j--)
            if(a[i]>a[j])
                dp_right[i]=max(dp_right[i],dp_right[j]+1);

    for(int i=1;i<=n;i++)
    {
        if(dp_left[i]+dp_right[i]-1>ans)
            ans=dp_left[i]+dp_right[i]-1;
    }
    ans=n-ans;

    for(int i=1;i<=n;i++)
    {
        if(dp_left[i]==1)
        {
            f1[i]=1;
            continue;
        }
        for(int j=1;j<=i-1;j++)
            if(dp_left[j]+1==dp_left[i] && a[j]<a[i])
                f1[i]+=f1[j];
    }
    for(int i=n;i>=1;i--)
    {
        if(dp_right[i]==1)
        {
            f2[i]=1;
            continue;
        }
        for(int j=n;j>=i+1;j--)
            if(dp_right[j]+1==dp_right[i] && a[i]>a[j])
                f2[i]+=f2[j];
    }

    for(int i=1;i<=n;i++)
        if(n-(dp_left[i]+dp_right[i]-1)==ans)
            num+=f1[i]*f2[i];

    cout<<ans<<" "<<num;
    return 0;
}

以上就爲五一歡樂測試的總結[笑]

有大佬會第三題的聯繫我啊!QQ:2789690129(備註CSDN)

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