目录
1.比赛概况
比赛共4题,每题100分,共400分。赛时拿到30分,T2得30分。
2.比赛过程
正常审题,审完觉得都挺难的,就从T1开始做的,坐了一个半小时多再一看题发现理解错了,就重做,重做完了就做T2(这里我还不知道我初始化没放循环里,哎呀!!!!!!!!真的服了!!!!6啊!!!!!!! 并且就剩一个多小时了)T2因为没时间了,就打了个暴力,想着能过4个点就行,结果题面信息不全又丢了10分;完事就去看T3,T3一个SPJ的题,本来看三层循环不会爆,但想不到代码,一通骗分之后没时间了,T4就随便打了几行代码就交上了
最后只有30分
3.解题报告
T1.复读机(repeater)
题意
分析
在每次遇到字母的时候就对它进行拼接,拼接之前检查一下这是不是每个字母串的第一个字母,如果是,则将上一个字母串拼接 cnt-1 次
每次遇到数字就对他进行计数,如果这是字符串的最后一位,那么拼接并提前结束
AC代码
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
string a,ans="",ans1;int cnt=1;//jishu是第几个字符串,cnt是重复次数
int main(){
// freopen
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t,n;
cin >> t;
for(int i=1;i<=t;i++){
ans=ans1="";
cin >> n >> a;
for(int j=0;j<n;j++){
if(a[j]>='0'&&a[j]<='9'){
cnt=cnt*10+a[j]-48;
if(j==n-1){
for(int k=1;k<cnt;k++) ans+=ans1;
ans1=ans;
}
}
else{//字母
ans1=ans;
if(cnt){
for(int k=1;k<cnt;k++) ans+=ans1;
cnt=0;}
ans+=a[j];
ans1=ans;
}
}
cout << ans << endl;
cnt=0;
}
// fclose
return 0;
}
T2.小可的矛与盾(spearshield)
题意
分析
用前缀和求每个区间的攻击/防御值,之后遍历每个可能的断点pos即可。
AC代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
using namespace std;
int main(){
// freopen
int n,sum1[100005]={0},sum2[100005]={0};
long long minn=9223372036854775807;//最大值
string a;
cin >> n >> a;
a=" "+a;
for(int i=1;i<=n;i++){
if(a[i]=='0'){
sum1[i]=sum1[i-1]+i;//更新
sum2[i]=sum2[i-1];//继承
}
if(a[i]=='1'){
sum2[i]=sum2[i-1]+i;
sum1[i]=sum1[i-1];
}
}
for(int i=0;i<=n+1;i++){
int linshiyong=abs(sum1[i]-(sum2[n]-sum2[i]));
minn=minn<linshiyong?minn:linshiyong;
}
cout << minn;
// fclose
return 0;
}
T3.不合法字符串(linegality)
题意
分析
一道SPJ题,三层循环可以遍历出每组数据每个字符串中的不合法字符串,并将它们用“*”替换掉
AC代码
#include<bits/stdc++.h>
using namespace std;
int T,n,m;
string str[100000],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++){//找哪个[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]){
//以[i]为结尾的单词
tgt[i]='*';
}
}
}
for(int i=1;i<=n;i++)
cout<<tgt[i];
cout<<endl;
}
// fclose
return 0;
}
T4.虚假的珂朵莉树(kodori)
本题涉及部分进阶算法/数据结构知识,AC代码仅作参考
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<<" ";
// fclose
return 0;
}
4.赛后总结
现在的分数是越来越低了。。。。
实际上是一百三十分的,但是由于我自己不注意。。。。
以后得注意了啊!!!!!!!!