Codeforces Round #744 (Div. 3)【A-E1】

后面的题没做,不想补了。因为最近才开始在cf上刷题,打比赛。
主要是英语太差,div3目前打算到可以很快的AC前5道,再开始攻克前6道。
以此类推,慢慢的进步吧。

A. Casimir’s String Solitaire【水题】

在这里插入图片描述
https://codeforces.com/contest/1579/problem/A
判断B的数量等不等于A的数量加上C的数量

#include<bits/stdc++.h>
using namespace std;
int main(void)
{
    
    
	int t; cin>>t;
	while(t--)
	{
    
    
		string s; cin>>s;
		int cnt1=0,cnt2=0,cnt3=0;
		for(int i=0;i<s.size();i++)
		{
    
    
			if(s[i]=='A') cnt1++;
			else if(s[i]=='B')  cnt2++;
			else cnt3++;
		}
		if(cnt2==cnt1+cnt3) puts("YES");
		else puts("NO");
	}
}

B. Shifting Sort【难度: 一般 / 知识点:用队列模拟左移】

在这里插入图片描述
https://codeforces.com/contest/1579/problem/B
思路: 用一个B数组保存题目给的A数组,排序B数组。
用队列q来保存目前A数组。
遍历数组,将队列的头部元素和数组B的元素一一比较即可。
相等的话不用移动,不相等的话就模拟左移,直到到达指定的位置。

#include<bits/stdc++.h>
using namespace std; 
typedef long long int LL;
const int N=1e5*2+10;
LL a[N],b[N];
int main(void)
{
    
    
	int t; cin>>t;
	while(t--)
	{
    
    
		int n; cin>>n;
		queue<int>q;
		for(int i=0;i<n;i++) cin>>a[i],b[i]=a[i],q.push(a[i]);
		sort(b,b+n);
		vector<int>s1,s2,s3;//左边界,右边界,步数
		for(int i=0;i<n;i++)
		{
    
    
			if(b[i]!=q.front())
			{
    
    
				int cnt=0;//记录移动了多少步数 
				while(q.front()!=b[i]) 
				{
    
    
					cnt++;
					int temp=q.front(); q.pop();
					q.push(temp);
				}
				q.pop();
				s1.push_back(i+1),s2.push_back(n),s3.push_back(cnt);
			}else q.pop();
		}
		cout<<s1.size()<<endl;
		for(int i=0;i<s1.size();i++) cout<<s1[i]<<" "<<s2[i]<<" "<<s3[i]<<endl;
	}
	return 0;
}

C. Ticks【难度: 一般 / 知识点: 暴力枚举】

在这里插入图片描述
https://codeforces.com/contest/1579/problem/C
在这里插入图片描述
暴力枚举所有可以画的合法的对勾,将其对勾的每一个点标记为1。
最后看所有的" * " 的状态是不是都是 1 即可

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*2+10;
string s[N];
int st[25][25],backup[25][25];
int n,m,k;
void dfs(int xx,int yy)
{
    
    
    for(int len=20;len>=k;len--)//枚举所有的对勾的大小 
    {
    
    
        int x=xx+len,y=yy+len;//底部坐标 
        if(x>=n||y>=m) continue;
        if(s[x][y]!='*') continue;
        memcpy(backup,st,sizeof st);//先保存一下备份 
        bool flag=true;
        st[x][y]=1;
        for(int i=1;i<=len;i++)
        {
    
    
            int tempx=x-i,tempy=y-i;
            if(tempx>=n||tempx<0||tempy>=m||tempy<0) flag=false;
            if(s[tempx][tempy]!='*') flag=false;
            st[tempx][tempy]=1;
            tempx=x-i,tempy=y+i;
            if(tempx>=n||tempx<0||tempy>=m||tempy<0) flag=false;
            if(s[tempx][tempy]!='*') flag=false;
            st[tempx][tempy]=1;
        }
        if(!flag) memcpy(st,backup,sizeof st);//如果对勾不合法,恢复一下状态 
    }
}
int main(void)
{
    
    
	int t; cin>>t;
	while(t--)
	{
    
    
		cin>>n>>m>>k;
		memset(st,0,sizeof st);
		for(int i=0;i<n;i++) cin>>s[i];
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				if(s[i][j]=='*') dfs(i,j);//以找到的点默认为左端点 
				
		bool ans=true;
		for(int i=0;i<n;i++)
		    for(int j=0;j<m;j++)
		       if(s[i][j]=='*'&&st[i][j]==0) ans=false;
		       
		if(ans) puts("YES");
		else puts("NO");
	}
	return 0;
}

D. Productive Meeting【难度: 一般 / 知识点: 贪心/优先队列 】

在这里插入图片描述
https://codeforces.com/contest/1579/problem/D

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
typedef pair<int,int> PII;
const int N=1e5*2+10;
LL a[N];
int main(void)
{
    
    
	int t; cin>>t;
	while(t--)
	{
    
    
		int n; cin>>n;
		vector<pair<int,int>>ans,ve;
		for(int i=0;i<n;i++) cin>>a[i],ve.push_back({
    
    a[i],i});
		sort(ve.begin(),ve.end());
		priority_queue<PII>s1;//大根堆 
		priority_queue<PII, vector<PII>, greater<PII> >s2;//小根堆 
		for(int i=0;i<n/2;i++) if(ve[i].first) s2.push(ve[i]);//前一半放小根堆 
		for(int i=n/2;i<n;i++) if(ve[i].first) s1.push(ve[i]);//后一半放大根堆 

		while(s1.size()&&s2.size())//每次从大根堆和小根堆 取一个元素 
		{
    
    
		    auto temp1=s1.top(); s1.pop();
		    auto temp2=s2.top(); s2.pop();
		    ans.push_back({
    
    temp1.second,temp2.second});
		    temp1.first--;
		    temp2.first--;
		    if(temp1.first>=1) s1.push(temp1);
		    if(temp2.first>=1) s2.push(temp2);
		}
		while(s1.size()>=2)//当大根堆还有多余的两个元素时 
		{
    
    
		    auto temp1=s1.top(); s1.pop();
		    auto temp2=s1.top(); s1.pop();
		    temp1.first--;
		    temp2.first--;
		    ans.push_back({
    
    temp1.second,temp2.second});
		    if(temp1.first>=1)  s1.push(temp1);
		    if(temp2.first>=1)  s1.push(temp2);
		}
		while(s2.size()>=2)//当小根堆还有多余的两个元素时 
		{
    
    
		    auto temp1=s2.top(); s2.pop();
		    auto temp2=s2.top(); s2.pop();
		    temp1.first--;
		    temp2.first--;
		    ans.push_back({
    
    temp1.second,temp2.second});
		    if(temp1.first>=1)  s2.push(temp1);
		    if(temp2.first>=1)  s2.push(temp2);
		}
		cout<<ans.size()<<endl;
		for(int i=0;i<ans.size();i++) cout<<ans[i].first+1<<" "<<ans[i].second+1<<endl;
	}
	return 0;
}

其实不用那么的麻烦,直接用一个大根堆,每次取堆顶的俩元素即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
typedef pair<int,int> PII;
const int N=1e5*2+10;
LL a[N];
int main(void)
{
    
    
	int t; cin>>t;
	while(t--)
	{
    
    
		int n; cin>>n;
		vector<pair<int,int>>ans,ve;
		for(int i=0;i<n;i++) cin>>a[i],ve.push_back({
    
    a[i],i});
		sort(ve.begin(),ve.end());
		priority_queue<PII>s1;//大根堆 
		for(int i=0;i<n;i++) if(ve[i].first) s1.push(ve[i]);
		while(s1.size()>=2)
		{
    
    
		    auto temp1=s1.top(); s1.pop();
		    auto temp2=s1.top(); s1.pop();
		    temp1.first--;
		    temp2.first--;
		    ans.push_back({
    
    temp1.second,temp2.second});
		    if(temp1.first>=1)  s1.push(temp1);
		    if(temp2.first>=1)  s1.push(temp2);
		}
		cout<<ans.size()<<endl;
		for(int i=0;i<ans.size();i++) cout<<ans[i].first+1<<" "<<ans[i].second+1<<endl;
	}
	return 0;
}

E1. Permutation Minimization by Deque【难度: 简单 / 知识点:双端队列模拟】

在这里插入图片描述
https://codeforces.com/contest/1579/problem/E1
用双端队列模拟即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*2+10;
LL a[N];
int main(void)
{
    
    
	int t; cin>>t;
	while(t--)
	{
    
    
		int n; cin>>n;
		for(int i=0;i<n;i++) cin>>a[i];
		deque<int>q;
		for(int i=0;i<n;i++) 
		{
    
    
			if(q.size()==0) q.push_back(a[i]);
			else 
			{
    
    
				if(q.front()>=a[i]) q.push_front(a[i]);//放前面更小 
				else q.push_back(a[i]);//放后面 
			}
		}
		vector<int>ans;
		while(q.size()) ans.push_back(q.front()),q.pop_front();
		for(int i=0;i<ans.size();i++) 
		{
    
    
			if(i) cout<<" ";
			cout<<ans[i];
		}
		cout<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_46527915/article/details/120551414
今日推荐