2021天梯赛补题

感想

今年大家分数都很高,好多230+,然而我只有209(菜鸡流泪
去年拿了145是学校中游水平,今年仍然是中游QAQ,复盘一下大概就是状态不好+平常训练不注意细节(谁叫你天天玩的啊喂
不能说哪一道题有特别大的问题,但是每一道都出了点小问题叭,就内个拿不了全分,不说了,时隔两周我终于补题了

1. L1-8

L1-078 吉老师的回归 (15 分)
当时只拿了13分,不知道哪错了。妈耶,现在回头一看这么简单,当时可能是拿脚写的。。。
在s中找目标串x,s.find(x)找不到会返回-1。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e4+10;
int n,m;

int main(){
    cin>>n>>m;
    getchar();
    string ans="Wo AK le";
    for(int i=1;i<=n;i++){
        string s;
        getline(cin,s);
        if(s.find("qiandao")==-1&&s.find("easy")==-1){
            m--;
        }
        if(m==-1) ans=s,m--;
    }
    cout<<ans;
return 0;
}

2. L2-2

病毒溯源
这个题当时没拿满分qaq,用前项星存图排序应该出了点问题。然后下面补了两种满分代码。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e4+10;
int n,root,maxn;
vector<int> a[N],tmp,ans;
bool f[N];

void dfs(int u,int len){
    if(len>maxn){
        maxn=len;
        ans=tmp;
    }
    for(int i=0;i<a[u].size();i++){
        int j=a[u][i];
        tmp.push_back(j);
        dfs(j,len+1);
        tmp.pop_back();
    }
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        int k;cin>>k;
        while(k--){
            int x;cin>>x;
            a[i].push_back(x);
            f[x]=true;
        }
        sort(a[i].begin(),a[i].end());
    }
    for(int i=0;i<n;i++){
        if(f[i]==0) root=i;
    }
    dfs(root,1);
    cout<<maxn<<endl;
    cout<<root;
    for(int i=0;i<ans.size();i++){
        cout<<' '<<ans[i];
    }
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
typedef pair<ll,int> pii;
const int N=2e5+10,mod=1e9+7,P=131;
int n;
bool st[N];
int son[N];
int h[N],e[N],ne[N],idx;

void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int dfs(int u){
    int res=0;
    son[u]=-1;
    for(int i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        int dis=dfs(j);
        if(res<dis){
            res=dis;
            son[u]=j;
        }
        else if(res==dis){
            son[u]=min(son[u],j);
        }
    }
    return res+1;
}
int main(){
    memset(h,-1,sizeof h);
    cin>>n;
    for(int i=0;i<n;i++){
        int k;cin>>k;
        while(k--){
            int x;cin>>x;
            add(i,x);
            st[x]=true;
        }
    }
    int root=0;
    while(st[root]) root++;
    cout<<dfs(root)<<endl<<root;
    while(son[root]!=-1){
        root=son[root];
        cout<<' '<<root;
    }

return 0;
}

3. L2-3

清点代码库
这个题长知识了,vector容器之间也可以直接进行比较大小,以及当时忘记用scanf被卡了一个测试点。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e4+10;
int n,m,ans;

struct nobe{
    int cnt;
    vector<int> v;
}a[N],b[N];

bool cmp(nobe a,nobe b){
    if(a.cnt!=b.cnt) return a.cnt>b.cnt;
    return a.v<b.v;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        a[i].cnt=1;
        for(int j=0;j<m;j++){
            int x;scanf("%d",&x);
            a[i].v.push_back(x);
        }
    }
    sort(a,a+n,cmp);
    int k=0;
    for(int i=1;i<=n;i++){
        if(a[i].v==a[i-1].v) a[i].cnt=a[i-1].cnt+1;
        else {
            ans++;
            b[k++]=a[i-1];
        }
    }

    sort(b,b+k,cmp);
    cout<<ans<<endl;
    for(int i=0;i<k;i++){
        printf("%d",b[i].cnt);
        for(int j=0;j<m;j++) printf(" %d",b[i].v[j]);
        printf("\n");
    }
return 0;
}

4. L3-1

L3-028 森森旅游 (30 分)
0分题,当时看到就没思路,没想到还给过了样例,交上去就1分。
就前后各做一遍dij,然后注意memset给函数形参赋值时,要sizeof要加一个确实存在的数组。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<ll,int> pii;
const int N=4e5+10,mod=1e9+7;
const ll inf=0x3f3f3f3f3f3f3f3fll;
int n,m,t;
int e[N],h1[N],h2[N],ne[N],w[N],idx;
int v[N];
ll dis1[N],dis2[N];
bool st[N];

void add(int h[],int a,int b,int c){
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void dij(int h[],ll dis[],int start){
    memset(dis,0x3f,sizeof dis1);
    memset(st,0,sizeof st);
    dis[start]=0;
    priority_queue<pii,vector<pii>,greater<pii> >q;
    q.push({0,start});
    while(q.size()){
        auto t=q.top();
        q.pop();
        int u=t.second;
        if(st[u]) continue;
        st[u]=true;
        for(int i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(dis[j]>dis[u]+w[i]){
                dis[j]=dis[u]+w[i];
                q.push({dis[j],j});
            }
        }
    }
}

int main(){
    memset(h1,-1,sizeof h1);
    memset(h2,-1,sizeof h2);
    scanf("%d%d%d",&n,&m,&t);
    while(m--){
        int u,v,c,d;scanf("%d%d%d%d",&u,&v,&c,&d);
        add(h1,u,v,c);add(h2,v,u,d);
    }
    for(int i=1;i<=n;i++) scanf("%d",&v[i]);
    dij(h1,dis1,1);
    dij(h2,dis2,n);
    multiset<ll> s;
    for(int i=1;i<=n;i++){
        if(dis1[i]!=inf&&dis2[i]!=inf){
            ll x=dis1[i]+(dis2[i]+v[i]-1)/v[i];
            s.insert(x);
        }
    }
    while(t--){
        int p,value;cin>>p>>value;
        if(dis1[p]!=inf&&dis2[p]!=inf){
            s.erase(s.find(dis1[p]+(dis2[p]+v[p]-1)/v[p]));
            v[p]=value;
            s.insert(dis1[p]+(dis2[p]+v[p]-1)/v[p]);
        }
        printf("%lld\n",*s.begin());
    }

return 0;
}

5. L3-2

L3-029 还原文件 (30 分)
啊这个题当时哈希只拿了26分,有想过kmp但是不太记得咋写了
看别人题解有暴力dfs过的,正解是啥我也不知道~下面补一个暴力+哈希的满分解法

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
typedef pair<ll,int> pii;
const int N=2e5+10,mod=1e9+7,P=131;
int n,m,k;
ull p[N],h[N],g[N];
int ans[N],len[N];
bool st[N];

ull get(int l,int r){
    return h[r]-h[l-1]*p[r-l+1];
}
bool dfs(int u,int now){
    if(now==n) return true;
    for(int i=1;i<=m;i++){
        if(!st[i]&&g[i]==get(now,now+len[i]-1)){
            st[i]=true;
            ans[u]=i;
            if(dfs(u+1,now+len[i]-1)) return true;
            st[i]=false;
        }
    }
    return false;
}
int main(){
    cin>>n;
    p[0]=1,h[0]=0;
    for(int i=1;i<=n;i++){
        int x;cin>>x;
        p[i]=p[i-1]*P;
        h[i]=h[i-1]*P+x+1;
    }
    cin>>m;
    for(int i=1;i<=m;i++){
        cin>>len[i];
        for(int j=0;j<len[i];j++){
            int x;cin>>x;
            g[i]=g[i]*P+x+1;
        }
    }
    dfs(1,1);
    for(int i=1;i<=m;i++){
        cout<<ans[i];
        if(i!=m) cout<<' ';
    }
return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值