Codeforces Round 1017 (Div. 4)A~G 题解(蒟蒻见解)
传送门:https://codeforces.com/contest/2094
A - Trippi Troppi
用string读入扣出来每一个string的第一个单词输出即可
点击查看代码
#include <bits/stdc++.h>
#define PII pair<int,int>
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void solve()
{
string a,b,c,ans;
cin>>a>>b>>c;
ans+=a[0];
ans+=b[0];
ans+=c[0];
cout<<ans<<endl;
}
int main()
{
int T=1;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
B - Bobritto Bandito
因为这道题有多种答案,我们只需找到符合条件的简单答案即可
如果m<=r,我们可以让答案左为0,答案右边为m,保证答案区间是m(原来的l-r区间中)即可
如果m>r的话也是一样保证答案区间是m(原来的l-r区间中)即可
点击查看代码
#include <bits/stdc++.h>
#define PII pair<int,int>
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void solve()
{
int n,m,l,r,l1,r1;
cin>>n>>m>>l>>r;
if(m<=r)
{
l1=0;
r1=m;
}
else
{
l1=r-m;
r1=r;
}
cout<<l1<<" "<<r1<<endl;
}
int main()
{
int T=1;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
C - Brr Brrr Patapim
这道题的意思就是给你的矩阵的位置(i,j)相加就是它在排列中的位子,并推测出该排列
我们可以声明一个一维数组来存储排列中确定的值,并记录这个值,结束后遍历2*n中没有被存储的值和位置,对应后输出即可
点击查看代码
#include <bits/stdc++.h>
#define PII pair<int,int>
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void solve()
{
int a[2000]={0};
int n;
cin>>n;
int k;
bool st[2*n+10]={false};
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>k;
a[i+j]=k;
//cout<<"k"<<k<<endl;
st[k]=true;
}
}
int tmp;
for(int i=1;i<=2*n;i++)
{
if(!st[i])
{
tmp=i;
break;
}
}
//cout<<tmp<<endl;
for(int i=1;i<=2*n;i++)
{
if(a[i]==0)cout<<tmp<<" ";
else cout<<a[i]<<" ";
}
cout<<endl;
}
int main()
{
int T=1;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
D - Tung Tung Sahur
双指针
贪心
我们可以字符串p分为很多快,每一块都是连续的'L'or'R'
ps: LL | R | L | R | L | RR | L
字符串p的每一个'L'or'R'在字符串s中可能为一到两个对应字符
因此字符串s要满足每一个分块和字符串p对应,字符相同,并且每一块中字符字数要 p<=s<=2*p
因此我们使用双指针进行对比即可,记得谈判首字符
点击查看代码
#include <bits/stdc++.h>
#define PII pair<int ,int>
#define endl '\n'
#define int long long
using namespace std;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void solve()
{
string a,b;
cin>>a>>b;
int i=0,j=0;
while(i<a.size()||j<b.size())
{
if(i==a.size()||j==b.size()||a[0]!=b[0])
{
puts("NO");
return;
}
int s1=i,s2=j;
while(i<a.size()&&a[i]==a[s1])i++;
while(j<b.size()&&b[j]==b[s2])j++;
if(j-s2<i-s1||(i-s1)*2<j-s2)
{
puts("NO");
return;
}
}
puts("YES");
return;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
E - Boneca Ambalabu
位运算
异或
朴素写法,遍历n^2次求最大值(肯定超时了)
因此我们需要用到位运算的知识
关键思路: 异或操作的一个重要性质是位独立性
- 每一位的计算不依赖于其他位。因此我们可以分别计算每一位对总和的贡献。
如果k的第b位是1,那么它与所有第b位是0的数的异或结果在这一位会产生1
如果k的第b位是0,那么它与所有第b位是1的数的异或结果在这一位会产生1
因此我们可以提前预处理
出所有数组的每位的1的个数(n- 1的个数就是0的个数)
便利一次O(n)便可以得出每一个k对所有数的异或和,记录最值即可
点击查看代码
#include <bits/stdc++.h>
#define PII pair<int ,int>
#define endl '\n'
#define int long long
using namespace std;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void solve()
{
int n;
cin>>n;
vector<int> a(n);
for(auto &i:a)cin>>i;
vector<int> bits(30,0);
for(int i=0;i<30;i++)
{
int cnt=0;
for(int j=0;j<n;j++)
{
if(a[j]&(1<<i))cnt++;
bits[i]=cnt;
}
}
int ans=0;
for(int i=0;i<n;i++)
{
int sum=0;
for(int j=0;j<30;j++)
{
int bit=a[i]&(1<<j);
if(bit)
{
int qq=n-bits[j];
sum+=(qq*(1<<j));
}
else
{
int qq=bits[j];
sum+=(qq*(1<<j));
}
}
ans=max(ans,sum);
}
cout<<ans<<endl;
return;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
F - Trulimero Trulicina
模拟
一道较为简单的模拟题吧,不过要想全情况
当m不能被k整除时,按照1~k的顺序便利输出即可
当m能被k整除时,若按照上面输出上下可能存在相邻重复的可能性
因此只需要奇偶行错位一下即可
点击查看代码
#include <bits/stdc++.h>
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void solve()
{
int n,m,k;
cin>>n>>m>>k;
if(m%k)
{
int idx=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(++idx>k)idx=1;
cout<<idx<<" ";
}
cout<<endl;
}
}
else
{
for(int i=1;i<=n;i++)
{
for(int j=0;j<m;j++)
{
if(i&1)//偶数二进制第一位为0,奇为1
{
cout<<j%k+1<<" ";
}
else cout<<(j+1)%k+1<<" ";
}
cout<<endl;
}
}
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
G - Chimpanzini Bananini
双端队列
模拟
推公式
一道很吃操作的模拟题,如果用vector+rotate+reverse是会超时滴,这里就需要用到deque了
至于综合如何计算,如何推公式可以自行距离推导一下,并不难
三个操作:
s1移动数组元素,取出相应队头/尾放在尾/头
s2(本来是需要翻转数组的,但是我们直接从把另一头当队头即可,这就是deque的优势)
s==3读入,统计即可
点击查看代码
#include <bits/stdc++.h>
#define PII pair<int,int>
#define endl '\n'
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
void solve()
{
ll t,m,k;
for(cin>>t;t;t--){
deque<ll> q;
ll su=0,sz=0,res=0,cnm=0;
for(cin>>m;m;m--,cout<<res<<'\n'){
ll op,x; cin>>op;
if(op==1){
if(!cnm){k=q.back(); q.pop_back(); q.push_front(k);}
else{k=q.front(); q.pop_front(); q.push_back(k);}
res+=su-k*sz;
}
else if(op==2){
res=su*(sz+1)-res; cnm^=1;
}
else if(op==3){
cin>>x; su+=x; sz++; res+=sz*x;
if(!cnm)q.push_back(x);
else q.push_front(x);
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int T=1;
//cin>>T;
while(T--)
{
solve();
}
return 0;
}
这是本蒟蒻的第一篇题解,若有什么建议或者问题可以在评论区提出,我看到会及时回应的,很高兴能帮到你