CSP認證-第三次培訓(2019.9.6)

D題 火車購票

在這裏插入圖片描述
在這裏插入圖片描述

先來個錯誤示範,75分代碼:ios

#include <bits/stdc++.h>
using namespace std;
int n,cnt,tmps,rest[110],vis[110];
int main()
{ 
 
   
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=20;i++)
        rest[i]=5;//每排剩餘5張票
    for(int i=1;i<=n;i++)
    { 
 
   
        cin>>cnt;
        for(int j=1;j<=20;j++)//第j排
        { 
 
   
            if(rest[j]>=cnt)//第j排剩餘的票數大於等於cnt,則可讓cnt個座位相鄰
            { 
 
   
                tmps=0;//記錄出票數
                for(int k=(j-1)*5+1;k<=j*5;k++)//遍歷第j排座位,k爲座位編號
                { 
 
   
                    if(vis[k]==0)//第k個座位還未被購買
                    { 
 
   
                        vis[k]=1;
                        tmps++;
                        if(tmps<cnt)
                            printf("%d ",k);
                        else if(tmps==cnt)//已經出了cnt張票了,結束
                        { 
 
   printf("%d\n",k);rest[j]=rest[j]-cnt;break;}
                    }
                }
                break;
            }
        }
    }
    return 0;
}

爲何只得75分呢?c++

由於沒考慮這種狀況:當前要購買的票數大於每一排剩餘的票數,這樣沒法保證出票的是同一排的相鄰座位。舉個例子,如今每一排都只剩了3個座位,而要一次購買5張票,那麼只能第一排出2張票,第二排出3張票,這五張票不是都相鄰的。web

100分 AC代碼:svg

#include <bits/stdc++.h>
using namespace std;
int n,cnt,tmps,flag,rest[110],vis[110];
int main()
{ 
 
   
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=20;i++)
        rest[i]=5;//每排剩餘5張票
    for(int i=1;i<=n;i++)
    { 
 
   
        cin>>cnt;
        flag=0;
        for(int j=1;j<=20;j++)//第j排
        { 
 
   
            if(rest[j]>=cnt)//第j排剩餘的票數大於等於cnt,則可讓cnt個座位相鄰
            { 
 
   
                flag=1;//標記:能夠作到cnt個座位相鄰
                tmps=0;//記錄出票數
                for(int k=(j-1)*5+1;k<=j*5;k++)//遍歷第j排座位,k爲座位編號
                { 
 
   
                    if(vis[k]==0)//第k個座位還未被購買
                    { 
 
   
                        vis[k]=1;
                        tmps++;
                        if(tmps<cnt)
                            printf("%d ",k);
                        else if(tmps==cnt)//已經出了cnt張票了,結束
                        { 
 
   printf("%d\n",k);rest[j]=rest[j]-cnt;break;}
                    }
                }
                break;
            }
        }
        if(flag==0)//沒法作到cnt個座位相鄰
        { 
 
   
            tmps=0;
            for(int i=1;i<=100;i++)
            { 
 
   
                if(vis[i]==0)
                { 
 
   
                    vis[i]=1;
                    tmps++;
                    rest[(i-1)/5+1]--;
                    if(tmps<cnt)
                        printf("%d ",i);
                    else if(tmps==cnt)
                    { 
 
   printf("%d\n",i);break;}
                }
            }
        }
    }
    return 0;
}

B題 公共鑰匙盒

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
這題說實話,有點難度啊…url

看了一下網上其餘人寫的題解,是寫告終構體的多維排序。個人思路是遍歷全部時刻,若是如今遍歷的時刻有放回或取出就按題目要求進行操做。仔細想了一下,時間複雜度是O(n*n*s),極限數據能夠到1e10了,居然也給我AC了?好吧,我也只想到了暴力模擬…spa

若是想看多維排序解題的,能夠看看這篇文章:https://blog.csdn.net/L_xqqzldh/article/details/87938066.net

假的100分 AC代碼:rest

#include <bits/stdc++.h>
using namespace std;
bool vis[1010],is_out[10110],is_in[10110];
vector<int>out[10110],in[10110];
int n,m,mx,t1,t2,d,num,a[1010];
int main()
{ 
 
   
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        a[i]=i;
    for(int i=1;i<=m;i++)
    { 
 
   
        cin>>num>>t1>>d;
        t2=t1+d;
        out[t1].push_back(num);//保存t1時刻取出鑰匙的編號(可能取出多個)
        in[t2].push_back(num);//保存t2時刻放回鑰匙的編號(可能放回多個)
        is_out[t1]=1;//t1時刻有取出
        is_in[t2]=1;//t2時刻有放回
        mx=max(mx,t2);//mx爲最大時刻
    }
    memset(vis,1,sizeof(vis));//開始時全部掛鉤均被佔用
    for(int i=1;i<=mx;i++)//遍歷全部時刻
    { 
 
   
        if(is_in[i]==1)//i時刻有放回(先所有放回再取出)
        { 
 
   
            sort(in[i].begin(),in[i].end());//放回時要按從小到大放回
            for(int j=0;j<in[i].size();j++)
            { 
 
   
                for(int k=1;k<=n;k++)
                { 
 
   
                    if(vis[k]==0)//第k個掛鉤沒被佔用
                    { 
 
   
                        a[k]=in[i][j];//in[i][j]表示i時刻放回的第j把鑰匙的編號
                        vis[k]=1;
                        break;
                    }
                }
            }
        }
        if(is_out[i]==1)//i時刻有取出
        { 
 
   
            for(int j=0;j<out[i].size();j++)
            { 
 
   
                for(int k=1;k<=n;k++)
                { 
 
   
                    if(a[k]==out[i][j])//out[i][j]表示i時刻取出的第j把鑰匙的編號,找到了編號爲out[i][j]的鑰匙,將其取出
                    { 
 
   vis[k]=0;break;}
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
        i==n?printf("%d\n",a[i]):printf("%d ",a[i]);
    return 0;
}

A題 打醬油

在這裏插入圖片描述
在這裏插入圖片描述
100分 AC代碼:code

#include <bits/stdc++.h>
using namespace std;
int n,s,t1,t2,t3,ans;
int main()
{ 
 
   
    ios::sync_with_stdio(false);
    cin>>n;
    s=n/10;
    t1=s/5;
    t2=(s-t1*5)/3;
    t3=s-t1*5-t2*3;
    ans=7*t1+4*t2+t3;
    printf("%d\n",ans);
    return 0;
}

C題 最大波動

在這裏插入圖片描述
100分 AC代碼:xml

#include <bits/stdc++.h>
using namespace std;
int n,mx,a[1010];
int main()
{ 
 
   
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    mx=0;
    for(int i=2;i<=n;i++)
        mx=max(mx,abs(a[i]-a[i-1]));
    printf("%d\n",mx);
    return 0;
}

本文同步分享在 博客"nefu_ljw"(CSDN)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索