牛客小白月賽22部分題解

eg:除了C題沒看懂和I題看不懂之外,都是中文題就不寫題意了。
比賽傳送門

A-操作序列

題解:map應用大賞,本以爲要開unordered_map,後來發現隨便寫寫就過了。

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
using namespace std;
map<int,int>mmap;
map<int,int>::iterator it;
int n;
int main(){
    scanf("%d",&n);
    while(n--){
        int t,c;char ch;
        scanf("%d%c",&t,&ch);
        if(t==-1){
            if(mmap.empty())puts("skipped");
            else{
                printf("%d\n",mmap.begin()->second);
                mmap.erase(mmap.begin());
            }
        }else{
            if(ch==' '){
                scanf("%d",&c);
                it=mmap.lower_bound(t-30);
                if(it==mmap.end() || it->first>t+30)mmap[t]+=c;
            }else{
                if(mmap.count(t))printf("%d\n",mmap[t]);
                else puts("0");
            }
        }
    }
    return 0;
}

B-樹上子鏈

題解:算是樹上dp吧,用dfs求出每個根的最大兩個兒子,答案就是max(ans,a[root]+Maxson1+Maxson2)max(ans,a[root]+Maxson1+Maxson2)

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const ll INF=1e12;
const double eps=1e-6;
using namespace std;
int n;
ll a[maxn],ans=-INF;
vector<int>G[maxn];
ll dfs(int x,int fa){
    ll sum=0,cnt=0,num=0;
    for(int i=0;i<G[x].size();i++){
        int u=G[x][i];
        if(u==fa)continue;
        num=dfs(u,x);
        if(num>sum)cnt=sum,sum=num;
        else if(num>cnt)cnt=num;
    }
    ans=max(ans,a[x]+sum+cnt);
    return max(0ll,a[x]+sum);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1,-1);
    printf("%lld\n",ans);
    return 0;
}

D-收集紙片

題解:看到n的範圍很小,考慮暴力,直接枚舉全排列複雜度爲O(Tn!)O(Tn!)完全可以接受。

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const ll INF=1e9;
const double eps=1e-6;
using namespace std;
int n,m,stx,sty;
int k,x[20],y[20],a[11];
//next_permutation(a,a+n)
int cal(int a,int b,int c,int d){
    return abs(a-c)+abs(b-d);
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        scanf("%d%d",&stx,&sty);
        int ans=INF;
        scanf("%d",&k);
        for(int i=1;i<=k;i++)scanf("%d%d",&x[i],&y[i]);
        for(int i=0;i<k;i++)a[i]=i+1;
        int flag=1;
        while(flag){
            int nx=stx,ny=sty,tmp=0;
            for(int i=0;i<k;i++){
                tmp+=cal(nx,ny,x[a[i]],y[a[i]]);
                nx=x[a[i]],ny=y[a[i]];
            }
            tmp+=cal(nx,ny,stx,sty);
            ans=min(ans,tmp);
            flag=next_permutation(a, a+k);
        }
        printf("The shortest path has length %d\n",ans);
    }
    return 0;
}

E-方塊塗色

題解:簽到題,答案爲(nr)(mc)(n-r)*(m-c)

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
using namespace std;
int n,m,r,c;
int main(){
    while(~scanf("%d%d%d%d",&n,&m,&r,&c)){
        printf("%lld\n",1ll*(n-r)*(m-c));
    }
    return 0;
}

F-累乘數字

題解:簽到題

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
using namespace std;
int n,m,r,c;
int main(){
    while(~scanf("%d%d",&n,&m)){
        printf("%d",n);
        for(int i=1;i<=m;i++)printf("00");
        printf("\n");
    }
    return 0;
}

G-倉庫選址

題解:感覺巨難的一道題目(至今爲止沒有理解正解),四方暴力過了,牛客的評測機太猛了。

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const ll INF=1e12;
const double eps=1e-6;
using namespace std;
int n,m;
int a[110][110];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);
        ll ans=INF;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++){
                ll tmp=0;
                for(int k=1;k<=m;k++)
                    for(int l=1;l<=n;l++)
                        tmp+=1ll*(abs(i-k)+abs(j-l))*a[k][l];
                ans=min(ans,tmp);
            }
        printf("%lld\n",ans);
    }
    return 0;
}

H-貨物種類

題解:差分數組的思想,對於每一個倉庫i,開一個對應的Add數組和Del數組。對於每組讀入,Add[l]推入d物品,Del[r+1]推入d物品。之後進行一次掃描,即可獲得答案。

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
using namespace std;
map<int,int>mmap;
int n,m;
vector<int>L[maxn];
vector<int>R[maxn];
int main(){
    scanf("%d%d",&n,&m);
    while(m--){
        int l,r,d;
        scanf("%d%d%d",&l,&r,&d);
        L[l].push_back(d);
        R[r+1].push_back(d);
    }
    int cnt=0,ans=0,pos=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<L[i].size();j++){
            int x=L[i][j];
            if(mmap[x]==0)cnt++;
            mmap[x]++;
        }
        for(int j=0;j<R[i].size();j++){
            int x=R[i][j];
            if(mmap[x]==1)cnt--;
            mmap[x]--;
        }
        if(cnt>ans)ans=cnt,pos=i;
    }
    printf("%d\n",pos);
    return 0;
}

J-計算a+b

題解:高精度加法,簽到題

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
using namespace std;
char s[maxn];
string v,ans,a;
string add(string a,string b){
    v.clear();
    int tmp=0,t=0;
    reverse(a.begin(),a.end());
    reverse(b.begin(),b.end());
    while(a.size()!=b.size()){
        if(a.size()>b.size())b.push_back('0');
        else a.push_back('0');
    }
    for(int i=0;i<a.size();i++){
        tmp=a[i]+b[i]-'0'*2+t;
        t=tmp/10;
        v.push_back(tmp%10+'0');
    }
    if(t>0)v.push_back(t+'0');
    reverse(v.begin(),v.end());
    return v;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        ans.clear();a.clear();
        scanf("%s",&s);
        int len=strlen(s),flag=1,cnt=0,pos=0;
        for(int i=0;i<len;i++){
            if(s[i]=='+')cnt++,pos=i;
            else if(s[i]>='0' && s[i]<='9')continue;
            else flag=0;
        }
        if(cnt==0 || cnt>1)flag=0;
        if(pos==0 || pos==len-1)flag=0;
        if(!flag)puts("skipped");
        else {
            for(int i=0;i<pos;i++)a.push_back(s[i]);
            for(int i=pos+1;i<len;i++)ans.push_back(s[i]);
            ans=add(ans,a);
            cout<<ans<<endl;
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章