0129-0203部分校赛题解复盘

vj第一场

A题 https://codeforces.com/gym/103480/problem/A
该题让我们可以从回文串的特点入手,即两个相同的字母便可增加长度2,所以并不用思考该回文串要如何排序出来,而是看有多少对相同的字母,使用map<char,int>来记录字母出现的次数,再计算可以除以2的次数即可。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
void solve()
{
	int n;
	char c;
	map<char,int>q;
	cin>>n;
	while(n--)
	{
		cin>>c;
		q[c]++;
	}
	
	int ans=0;
	for(auto i:q) ans+=i.second/2;
	ans*=2;
	if(ans!=n) ans++;
	cout<<ans<<endl;

}

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
}

B题 https://codeforces.com/gym/103480/problem/B
该题利用前缀和和lower__bound去找到第一个大于等于s[i-1]+7777的s[x],再检测一下该数-7777是否为0,若为0则区间和为7777的cnt++。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
void solve ()
{
	int n,cnt=0;
	cin>>n;
	vector<int >q(n+1);
	for(int i=1;i<=n;i++)
	{
		cin>>q[i];
		q[i]=q[i]+q[i-1];//前缀和数组 
	}
    //从每个Si开始,当一个s找到一个刚好比他大7777的另一个sx时即说明从i-x这个区间的和为7777
	for(int i=1;i<=n;i++)
	{
		int k=*lower_bound(q.begin(),q.end(),q[i-1]+7777); 
		if(k-q[i-1]==7777) cnt++;
	}
	
	cout<<cnt<<endl;
}

int main(){
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
}

I题 https://codeforces.com/gym/103480/problem/I
使用vector<pair<int,string>>q并对其进行排序即可
sort(q.begin(),q.end(),greater<pair<int,string>>() );

点击查看代码
#include <bits/stdc++.h>
using namespace std;
void solve()
{
	int n;
	cin>>n;
	vector<pair<int,string> >q;
	for(int i=0;i<n;i++)
	{
		int x;
		string s;
		cin>>x>>s;
		q.push_back({x,s});//注意q.push_back()如果放的pair要用{} 
	}
	int k;
	cin>>k;
	sort(q.begin(),q.end(),greater<pair<int,string>>() );//按降序排序 
	cout<<q[k].second<<endl;
}




int main()
{
	int t=1;
	while(t--)
	{
		solve();
	}
	return 0;
	
 } 

D题https://codeforces.com/gym/103480/problem/M
题意相当于把1 3 5 6 4 2 变为 1 2 3 4 5 6只要双指针输出即可,即输出1 2再输出3 4在输出5 6

点击查看代码
#include <bits/stdc++.h>
using namespace std;
void solve(){
	string s;
	char k;
	vector<string>q;
	while(cin>>s){
		if(s.back()=='.'||s.back()=='!'||s.back()=='?')
		{
			k=s.back();
			s.pop_back();
			q.push_back(s);
			break;//遇到标点即为最后一个就跳出循环 
		}
		q.push_back(s);
	}
	
	for(int l=0,r=q.size()-1;l<=r;l++,r--){
		if(l==r) cout<<q[l];
		else{
			cout<<q[l]<<" "<<q[r];
			if(r-l>1) cout<<" ";//如果是放在最后就不要在标点符号前再加个空格 
		}

	}
	cout<<k;
	cout<<endl;
	
}



int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
	return 0;
}

VJ第二场

J题 https://codeforces.com/gym/104101/problem/J
奇数+奇数=偶数 偶数+偶数=奇数 偶数+奇数=奇数
所以当总和为偶数时 无论你怎么选 最后S1-S2都为偶数
反之当为奇数 无论怎么选 s1-s2都为奇数

点击查看代码
#include <bits/stdc++.h>
using namespace std;
void solve()
{
	int n,sum=0,a;
	
	cin>>n;
	while(n--){
		cin>>a;
		sum+=a;
	}
	if(sum%2==0) cout<<"Bob";
	else cout<<"Alice"; 
	
}

int main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int t=1;
	while(t--)
	{
		solve();
	}
	return 0;
}

C题https://codeforces.com/gym/104101/problem/C
这一题要用到一维的差分和lower__bound,区间加上一个整数用差分数组b[l]+c,b[r+1]-c

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N=500005;
int n,a[N],b[N],c[N],cnt=0;
void solve()
{

	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		c[i]=a[i];//用来存原来的数进行对比 
		b[i]=a[i]-a[i-1];//差分数组 
	}
	sort(c+1,c+n+1);//记得lower_bound 只能在有序的条件下进行查找 所以要排序 
	int l=1,r=n;
	b[l]+=9;
	b[r+1]-=9;
	for(int i=1;i<=n;i++) a[i]=a[i-1]+b[i];
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++)
	{
	 int k=*lower_bound(a+1,a+n+1,c[i]);
	  if(k-c[i]==0) cnt++;
	}
	
	cout<<n-cnt;
}


int main()
{
	int t=1;
	while(t--)
	{
		solve();
	}
	return 0; 
}

2024 蓝桥杯模拟赛 2 (div1+div2)

P8845 [传智杯 #4 初赛] 小卡和质数
https://www.luogu.com.cn/problem/P8845?contestId=155198
补充一下二进制运算的知识点:
与运算:对应二进制中的每一位,只有两个对应的位都为1,结果才为1。
位运算符为A&B

或运算:对应的二进制中的每一位,只要两个对应的位有一个为1,结果为1
位运算符为A|B

非运算:对应二进制中的每一位,0变为1,1变为0
位运算符~A

异或运算:对应的二进制中的每一位,只有 两个 对应的位不相同才为1
位运算符A^B

从第一个质数2开始,然后是3,5,7......从5开始便会对二进制的第二位以上产生贡献,因此只有2和3的异或值可能为1 经过位运算2和3的异或值确实为1

点击查看代码
#include <bits/stdc++.h>
using namespace std;

int main()
{
	int n,a,b;
	cin>>n;
	while(n--)
	{
		cin>>a>>b;
		if((a==2&&b==1)||(a==1&&b==2)) cout<<"Yes"<<endl; //第一个质数为2 第二个质数为3,但是先举例第一个再举例第二个和先举例第二个再举例第一个是两种情况
		else cout<<"No"<<endl;
	}
	
	return 0;
	
}

P8662 [蓝桥杯 2018 省 AB] 全球变暖
https://www.luogu.com.cn/problem/P8662?contestId=155198
dfs中简单的连通块问题,先计算淹没前有几个岛屿,再计算淹没后剩余几个,相减几个,但是淹没的岛屿不能作为搜索的起点。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
char c1[1005][1005],c2[1005][1005];//c1为淹没前的岛屿图,c2为淹没后 
int dx[]={-1,0,1,0},dy[]={0,1,0,-1},ans1,ans2,n; 
void dfs1(int x,int y)
{
	c1[x][y]='+';
	for(int i=0;i<4;i++)
	{
		int a=x+dx[i],b=y+dy[i];
		if(c1[a][b]=='#'&&a>0&&a<=n&&b>0&&b<=n){
			dfs1(a,b);
		}
	}
	 return ;	
}

void dfs2(int x,int y)
{
	c2[x][y]='.';
	for(int i=0;i<4;i++)
	{
		int a=x+dx[i],b=y+dy[i];
		if(c2[a][b]!='.'&&a>0&&a<=n&&b>0&&b<=n){//就是防止连在一起的几个##造成计数错误,所以把其也变成. 
			dfs2(a,b);
		}
	}
	 return ;	
}

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>c1[i][j];
			c2[i][j]=c1[i][j];
		}
	}

	//对岛屿进行淹没
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(c2[i][j]=='#'&&(c2[i-1][j]=='.'||c2[i][j+1]=='.'||c2[i+1][j]=='.'||c2[i][j-1]=='.'))
			c2[i][j]='-';
		}
	 }
	 	//找淹没前有多少个岛屿 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){ 
			if(c1[i][j]=='#') 
			{
				ans1++;
				dfs1(i,j);
			}
		}
	}
	 //找淹没后剩余几个岛屿 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){ 
			if(c2[i][j]=='#') 
			{
				ans2++;
				dfs2(i,j);
			}
		}
	}
	
	cout<<ans1-ans2;
	
}

posted on 2024-02-03 19:12  swj2529411658  阅读(30)  评论(0)    收藏  举报

导航