后面的题没做,不想补了。因为最近才开始在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;
}