Contest1021赛后总结

今天这场打的不是很好,能出的题目没有全出。都是一些思路上的问题。

第一道开的题是I题 :最长回文串长度

在这里插入图片描述
第一眼看上去很难,是个回文问题,但是题目不要求顺序,那就很容易了,哈希存值,偶数个全加上,奇数个减一加上,同时标记一下,因为回文串中心可以有单独的一个字符。代码如下:

#include<bits/stdc++.h>
using namespace std;
char s[10005];
int a[30],b[30];
int main(){
	while(scanf("%s",s)!=EOF){
		int len=strlen(s);
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		for(int i=0;i<len;i++){
			if(s[i]>='a'&&s[i]<='z'){
				a[s[i]-'a']++;
			}else{
				b[s[i]-'A']++;
			}
		}
		bool flag=false;
		int sum=0;
		for(int i=0;i<26;i++){
			if(a[i]&1){
				sum+=a[i]-1;
				flag=true;
			}else{
				sum+=a[i];
			}
			if(b[i]&1){
				sum+=b[i]-1;
				flag=true;
			}else{
				sum+=b[i];
			}
		}
		if(flag)sum++;
		printf("%d\n",sum);
	}
	return 0;
} 

在这里插入图片描述

下一道是G题,之前做过类似的题目,刚开始写反了符号没搓出样例,就试着交了一发bfs,果然炸内存了。然后重新写,因为奇数只能加,偶数才能除2,所以还是很好写的。代码如下:

#include<bits/stdc++.h>
using namespace std;
int a,b;
int main(){
	while(scanf("%d %d",&a,&b)!=EOF){
		if(a>b){
			printf("%d\n",a-b);
		}else{
			int sum=0;
			while(b>a){
				if(b&1){
					b++;
				}else{
					b/=2;
				}
				sum++;
			}
			sum+=abs(a-b);
			printf("%d\n",sum);
		}
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述
然后是c题,简单的结构体快排题,没什么坑,只要根据条件把不要的数据过滤掉就行。

#include<bits/stdc++.h>
using namespace std;
struct node{
	int id,w,e,r,g;
	friend bool operator < (const node &a,const node &b){
		if(a.w!=b.w)return a.w>b.w;
		return a.id>b.id;
	}
}k[10005],now;
int ans;
int main(){
	int n,a,b,c;
	while(scanf("%d %d %d %d",&n,&a,&b,&c)!=EOF){
		ans=0;
		for(int i=0;i<n;i++){
			scanf("%d %d %d %d %d",&now.id,&now.w,&now.e,&now.r,&now.g);
			if((a==1&&now.e==0)||(now.r>b)||(now.g>c)){
				
			}else{
				k[ans++]=now;
			}
		}
		sort(k,k+ans);
		for(int i=0;i<ans;i++){
			printf("%d %d %d %d %d\n",k[i].id,k[i].w,k[i].e,k[i].r,k[i].g);
		}
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述
然后翻到了h题,看题面就知道是线段树,单点更新加减只要update正负数就行,不是很难,一道模板题。代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAXN 50005
struct node{
	int l,r;
	ll sum;
}k[MAXN<<2];
inline void build(int l,int r,int x){
	k[x].l=l;
	k[x].r=r;
	if(l==r){
		scanf("%lld",&k[x].sum);
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,x<<1);
	build(mid+1,r,x<<1|1);
	k[x].sum=k[x<<1].sum+k[x<<1|1].sum;
}
inline void update(int root,int val,int x){
	if(k[x].l==k[x].r){
		k[x].sum+=val;
		return;
	}
	int mid=(k[x].l+k[x].r)>>1;
	if(root<=mid)update(root,val,x<<1);
	if(root>mid)update(root,val,x<<1|1);
	k[x].sum=k[x<<1].sum+k[x<<1|1].sum;
}
inline ll query(int l,int r,int x){
	if(l<=k[x].l&&r>=k[x].r){
		return k[x].sum;
	}
	int mid=(k[x].l+k[x].r)>>1;
	ll sum=0;
	if(l<=mid)sum+=query(l,r,x<<1);
	if(r>mid)sum+=query(l,r,x<<1|1);
	return sum;
}
int main(){
	int t,ans=1;
	scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		build(1,n,1);
		char s[6];
		printf("Case %d:\n",ans++);
		while(scanf("%s",s)){
			if(s[0]=='E')break;
			if(s[0]=='A'){
				int a,b;
				scanf("%d %d",&a,&b);
				update(a,b,1);
			}else if(s[0]=='S'){
				int a,b;
				scanf("%d %d",&a,&b);
				update(a,-b,1);
			}else{
				int a,b;
				scanf("%d %d",&a,&b);
				printf("%lld\n",query(a,b,1));
			}
		}
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述
这题看到就觉得会卡掉dfs,然后就没去写,后面看榜单过了不少人,然后仔细想了想,其实也不难。
题解:题解链接

在这里插入图片描述
在这里插入图片描述
之后是本来就写好了的k题,一直找不出坑点。
直到后面想到因为地面是字符,采取的方法是map映射,所以可以能导致起点和终点相同的情况下没有输出0;加了一行代码救过了;

#include<bits/stdc++.h>
using namespace std;
#define inf 1000005
#define N 255
int val[N][N];
int dist[N],vis[N];
unordered_map<string,int>num;
int n,s,e,ans;
inline int minnnn(int a,int b){
	return a>b?b:a;
}
inline void dijkstra(){
	for(int i=0;i<ans;i++){
		dist[i]=val[s][i];
		vis[i]=0;
	}
	dist[s]=0;
	vis[s]=1;
	for(int i=1;i<ans;i++){
		int minn=inf;
		int a=-1;
		for(int j=0;j<ans;j++){
			if(!vis[j]&&minn>dist[j]){
				minn=dist[j];
				a=j;
			}
		}
		if(a==-1)return;
		vis[a]=1;
		for(int j=0;j<ans;j++){
			if(!vis[j]&&val[a][j]!=inf){
				if(dist[j]>dist[a]+val[a][j]){
					dist[j]=dist[a]+val[a][j];
				}
			}
		}
	}
}
int main(){
	ios::sync_with_stdio(false);
	while(cin>>n){
		if(n==-1)break;
		string start,end;
		num.clear();
		cin>>start>>end;
		num[start]=s=0;
		num[end]=e=1;
		ans=2;
		for(int i=0;i<155;i++){
			for(int j=0;j<155;j++){
				if(i!=j)val[i][j]=inf;
				else val[i][j]=0;
			}
		}
		for(int i=0;i<n;i++){
			string a,b;
			int c;
			cin>>a>>b>>c;
			int aa,bb;
			if(num.find(a)==num.end()){
				num[a]=aa=ans++;
			}else{
				aa=num[a];
			}
			if(num.find(b)==num.end()){
				num[b]=bb=ans++;
			}else{
				bb=num[b];
			}
			val[aa][bb]=val[bb][aa]=minnnn(c,val[aa][bb]);
		}
		dijkstra();
		if(start==end)dist[1]=0;
		cout<<(dist[1]==inf?-1:dist[1])<<endl;
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述

最后出的一道题是B题,这题刚开始是自己画图推的,所以推错了,怎么都想不明白,最后写了一发dfs,求出:2 8 16 28 44,发现每次递增的数都会加4.然后就很简单了。

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll m[100005];
int main(){
	m[1]=2;
	m[2]=8;
	ll sum=8;
	for(int i=3;i<=100000;i++){
		m[i]=m[i-1]+sum;
		sum+=4;
	}
	int n;
	while(scanf("%d",&n)!=EOF){
		printf("%lld\n",m[n]);
	}
	return 0;
}

赛后补题,E题:
在这里插入图片描述
在这里插入图片描述
题解链接:点击跳转

D题:
在这里插入图片描述
在这里插入图片描述
题解:https://blog.csdn.net/weixin_43823753/article/details/104524638

J题:
在这里插入图片描述
在这里插入图片描述
题解:https://blog.csdn.net/weixin_43823753/article/details/104524863

总结:还是太菜了,很多题目想复杂了,本来J题也不难,刚开始看错题目了导致后面没有去想这道题,导致了没有出。
之后再把题目补完。之后的训练也不能放松,好好利用时间提高自己的水平。

发布了35 篇原创文章 · 获赞 3 · 访问量 897

猜你喜欢

转载自blog.csdn.net/weixin_43823753/article/details/104505943
今日推荐