复赛模拟Day4补题报告

复赛模拟Day4补题报告

题目概况:总分400分,赛时100分,A题100分,BCD题0分

比赛过程:先用模拟做了B题 (反正是0分),又做了做C题,还是没拿分,去看了看A题,用了整整1小时(准确来说是60min又3.1415926秒 )终于过了,(不然就带个0蛋回家了

题解报告:

(1)复读机

题目描述:现在给定一个长度为 n 的仅包含小写字母和数字的字符串,字母表示需要复读的消息,数字表示要复读的次数。输出共 t 行,每行一个字符串表示需要复读的内容。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int t,n;
string s;
char a[500005];
int main(){
	cin>>t;
	while(t--){
		int cnt=0;
		cin>>n>>s;
		for(int i=0;i<n;++i){
			if(s[i]>='a'&&s[i]<='z'){
				cnt++;
				a[cnt]=s[i];
			}
			if(s[i]>='1'&&s[i]<='9'){
				int sum=0;
				int k=i;
				while(s[k]>='0'&&s[k]<='9'){
					sum=sum*10+(s[k]-48);
					k++;
				}
				int maxn=0;
				for(int p=2;p<=sum;++p){
					for(int i=1;i<=cnt;++i){
						maxn=max(maxn,(p-1)*cnt+i);
						a[(p-1)*cnt+i]=a[i];
					}
				}
				cnt=max(cnt,maxn);
			}
		}
		for(int i=1;i<=cnt;++i){
			cout<<a[i];
		}
		cout<<"\n";
	}
	return 0;
} 

(2) 小可的矛与盾

题目描述:有一个部队,n名战士,其中1代表盾兵,0代表矛兵,每个战士的战斗值为他们的编号,求矛兵和盾兵总战斗值绝对值最小多少。
AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,a[100005],b[100005];
string s;
int main(){
    cin>>n>>s;
    s="*"+s;
    for(int i=1;i<=n;++i){
        if(s[i]=='1'){
            a[i]=a[i-1];
        }
        else{
            a[i]=a[i-1]+i;
        }
    }
    for(int i=n;i>=1;--i){
        if(s[i]=='1'){
            b[i]=b[i+1]+i;
        }
        else{
            b[i]=b[i+1];
        }
    }
    ll minn=min(a[n],b[1]);
    for(int i=1;i<=n;++i){
        ll k=abs(a[i]-b[i+1]);
        minn=min(minn,k);
    }
    cout<<minn;
    return 0;
}

(3) 不合法字符串

题目描述:现在给出若干个不合法的字符串s[i], 和一篇小说str,小可需要把str 中的不合法字符串用星号替换掉。当然小可是一个很聪明的审核员,他会用最少的星号替换字符串。输出替换完成后的字符串。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int t,n,m;
string str[100005],tgt;
int main(){
    cin>>t;
    while(t--){
        cin>>m;
        for(int i=1;i<=m;++i){
            cin>>str[i];
        }
        cin>>tgt;
        n=tgt.length();
        tgt=' '+tgt;
        for(int i=1;i<=n;++i){
            for(int j=1;j<=m;++j){
                if(i<str[j].length()){
                    continue;
                }
                if(tgt.substr(i-str[j].length()+1,str[j].length())==str[j]){
                    tgt[i]='*';
                }
            }
        }
        for(int i=1;i<=n;++i){
            cout<<tgt[i];
        }
        cout<<endl;
    }
    return 0;
}

(4) 虚假的珂朵莉树

题目描述:小可有一棵树,有 n 个节点,根节点为 1, 每个节点都有一个权值。设每个节点与根节点距离是这个节点的深度。小可会在这棵树上增加 m 条虚假边,任意一条虚假边不会和原来的树边或其他虚假边重合(增加的虚假边不影响节点深度)。之后小可会进行 q 次操作:操作1: 让结点 u 的权值增加 k ,并对与结点 u 相邻的结点中,深度比结点 u 小的结点重复操作1。操作2:让结点 u 的权值增加 k ,并对与结点 u 相邻的结点中,深度比结点 u 大的结点重复操作2。小可想知道,经过 q 次操作之后,所有的节点的权值是多少。
AC代码:

#include<bits/stdc++.h>
#define pr pair<int,int>
#define mk make_pair
using namespace std;
const long long p=1e9+7;
struct node{
    int to,next;
}e[5000005];
vector<pr> g;
long long a[1000005],up[1000005],down[1000005];
int n,m,q,cnt,head[1000005],d[1000005];
void add(int u,int v){
    e[++cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}
void dfs(int u,int fa){
    g.push_back(mk(d[u],u));
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(v==fa){
            continue;
        }
        d[v]=d[u]+1;
        dfs(v,u);
    }
}
int main(){
    cin>>n>>m>>q;
    for(int i=1;i<=n;++i){
        cin>>a[i];
    }
    for(int i=1;i<=n-1;++i){
        int u,v;
        cin>>u>>v;
        add(u,v);
        add(v,u);
    }
    dfs(1,1);
    for(int i=1;i<=m;i++){
        int u,v;
        cin>>u>>v;
        add(u,v);
        add(v,u);
    }
    for(int i=1;i<=q;i++){
        int pd,u,v;
        cin>>pd>>u>>v;
        if(pd==1){
            up[u]=(up[u]+v)%p;
        }
        else{
            down[u]=(down[u]+v)%p;
        }
    }
    sort(g.begin(),g.end());
    for(int i=0;i<g.size();++i){
        int x=g[i].second;
        for(int j=head[x];j;j=e[j].next){
            int y=e[j].to;
            if(d[y]>d[x]){
                down[y]=(down[y]+down[x])%p;
            }
        }
    }
    reverse(g.begin(),g.end());
    for(int i=0;i<g.size();i++){
        int x=g[i].second;
        for(int j=head[x];j;j=e[j].next){
            int y=e[j].to;
            if(d[y]<d[x]){
                up[y]=(up[y]+up[x])%p;
            }
        }
    }
    for(int i=1;i<=n;++i){
        cout<<(a[i]+up[i]+down[i])%p<<" ";
    }
    return 0;
}

赛后总结:本场比赛出现了代码实现不正确的问题,以后要多思考,找回不必要的失分。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值