Codeforces Round 944 (Div. 4)

知识点模块

1. ai xor aj<=4
意味着两个数字的二进制位,只能有后两位的二进制位不同,因为如果第三位二进制位不同,就会出现异或的结果大于4
2.要有化曲为直的思想
学会把曲线上的坐标转为直线,说不定会有意想不到的结果

B. Different String
这一题只要检查一下是否全部为一个字母即可,如果有不同的字母,我们就把第一个和从0开始的第一个字母不同的字母标记一下,然后从标记处开始输出再输出0到标记处实现交换,当然可以参考官方的解答,遇到不同的两两交换也是行的
1.我自己的代码

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve()
{
	string s;
	cin>>s;
	int pos=0,flag=0,cnt=0;
	map<char,int>mp;
	for(int i=0;i<s.size();i++)
	{
		if(mp[s[i]]==0){
			cnt++;
			mp[s[i]]++;
		}
		if(s[i]!=s[0]&&flag==0)
		{
			pos=i;
			flag=1;
		}
	}
	if(cnt==1) cout<<"NO"<<endl;
	else {
		cout<<"YES"<<endl;
		for(int i=pos;i<s.size();i++) cout<<s[i];
		for(int i=0;i<pos;i++) cout<<s[i];
		cout<<endl;
	}
	
}


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

C. Clock and Strings
这题的思路是化曲为直,其实我们可以想象一下,把圆从12处拉开成一条直线,那么如果两条直线相交则一定区间一定会有重叠的部分,那么不相交的只有包含关系和两者没有重叠部分的关系,所以只需要取一下两点的最大最小值讨论一下即可

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve()
{
	int a,b,c,d;
	cin>>a>>b>>c>>d;
	int max1=max(a,b),max2=max(c,d),min1=min(a,b),min2=min(c,d);
	if(min1>min2&&max1<max2||min2>min1&&max2<max1) cout<<"no"<<endl;
	else if(max1<min2||max2<min1) cout<<"no"<<endl;
	else cout<<"yes"<<endl;
	
	
}


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

D. Binary Cut
1.想要把序列弄成由0到1的有序排列,我们一定要有01这种连接的部分,而且只需要一个这种连接的部分即可,当然它可以是00001,001,000001等等
2.当我们从左往右遍历字符串的时候,我们只要遇到一个与上一个字符不同的,便是一个数据块(只有0和只有1的数字块),那么答案就是数据块的数量,再看有无01类似这样的连接块,有的话就是数据块-1,没有就是数据块的数量

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve()
{
	string s;
	cin>>s;
	int res=0;
	bool check=0;
	for(int i=0;i<s.size();i++)
	{
		res+=(s[i]!=s[i+1]);
		if(s[i]=='0'&&s[i+1]=='1') check=1;
	}
	cout<<res-check<<endl;
	
}


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

E. Find the Car
1.因为给出的每个已知点间的每一段速度是固定的,所以我们的思路就是先二分出第一个大于等于该查询值的路程下标,然后该下标-1,便是第一个小于该路程值已知点的下标,答案便是已知的花费时间+该段的差值/该段的固定速度,可以直接开int就能过

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve()
{
	int n,k,q;
	cin>>n>>k>>q;
	vector<int>a(k+1),b(k+1);
	//a存的已知到达的点的数值
	//b存的到达对应点的时间
	//那么(a[i]-a[i-1])/b[i]-b[i-1]为每段区间的速度 
	for(int i=1;i<=k;i++) cin>>a[i];
	for(int i=1;i<=k;i++) cin>>b[i];
	while(q--)
	{
		int x;
		cin>>x;
		if(x==0){
			cout<<"0"<<endl;
			continue;
	}
		int pos=lower_bound(a.begin(),a.begin()+k,x)-a.begin();
		//pos为第一个大于或等于该路程值的下标 
		//cout<<pos<<endl;
		int len=x-a[pos-1];
		int tim=len*(b[pos]-b[pos-1])/(a[pos]-a[pos-1]);
		cout<<b[pos-1]+tim<<endl;
	}
	
}


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

F. Circle Perimeter
1.虽然是计算四个象限所有的点,但是我们可以通过计算一个象限的点再*4即可,直接枚举0-x的格点,然后验证一下是否符合,但是这样是超时的,那我们就操作一下,把一些不合格的点预处理一下,这样就可以过了,总结来说就是枚举验证即可

点击查看代码
#include <bits/stdc++.h>
#define int long long
#define mod 100000007;
using namespace std;
void solve()
{
	int r,ans=0;
	cin>>r;
	int y=r;
	for(int i=0;i<=r;i++)
	{
        //因为如果这个高度不符合了,x在增大后面的格点也是不符合的
		while(i*i+y*y>=(r+1)*(r+1))
		{
			y--;
		}
		
		int top=y;
		while(i*i+top*top>=r*r&&top>0)
		{
			ans++;
			top--;
		}
		
	}
	cout<<ans*4<<endl;
	
}


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

G. XOUR
这个题目首先要理解一下这个ai XOR aj小于4的含义,也就是说,只允许每个数字的后两个后进制为不相同,前面的进制位都必须相同,因为但凡有一个不相同,那么异或的结果就会大于4,所以我们可以先对该数字右移两位,把这两个比特覆盖掉。然后我们可以开一个map里面存数字和优先队列,让这个几个数自动从小到大排序,然后遍历,数组那么每个数字就相当于这个队列的序号,从对应的队列取排序好的数就行了

点击查看代码
#include <bits/stdc++.h>
#define int long long
#define mod 100000007;
using namespace std;
void solve()
{
	
	map<int,priority_queue<int,vector<int>,greater<int> > >mp;
	int n;
	cin>>n;
	vector<int>a(n+1);
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		mp[a[i]>>2].push(a[i]);
	}
	
	for(int i=1;i<=n;i++)
	{
		cout<<mp[a[i]>>2].top() <<" ";
		mp[a[i]>>2].pop();
	}
	
	cout<<endl;
}


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

posted on 2024-05-12 16:22  swj2529411658  阅读(64)  评论(0编辑  收藏  举报

导航