Codeforces Round 906 (Div. 2)

Codeforces Round 906 (Div. 2)

A. Doremy’s Paint 3

构造

给你一个数列,任意排序,使得相邻两项的和为k,判断是否存在这样的构造

b 1 + b 2 = b 2 + b 3 = … … = k b_1+b_2=b_2+b_3=……=k b1+b2=b2+b3=……=k

显然,b1如果固定,那么b2=k-b1,b3=b1

也就是数列a里面至多2个元素。

若数列a内有1个元素,则YES

若数列a内有两个元素,如果这两个元素能满足交替进行的数量那么也是YES

也就是:num1-num2<=1

这两个元素的个数只差不能大于1.

否则NO

#include<bits/stdc++.h>
using namespace std;

#define int long long
#define ll long long

void slove(){
   int n;
   cin>>n;
   vector<int> a(n);
   for(int i=0;i<n;i++)cin>>a[i];
   map<int,int> m;
   for(int i=0;i<n;i++){
       m[a[i]]++;
   }
   if(m.size()>2)cout<<"NO"<<endl;
   else if(m.size()==1){
       cout<<"YES"<<endl;
   }
   else{
       auto it=m.begin();
       it++;
       int first=m.begin()->second;
       int second=it->second;
       
       if(m.begin()->second == it->second)cout<<"YES"<<endl;
       else if (abs(first-second)==1)cout<<"YES"<<endl;
       else cout<<"NO"<<endl;
   }
}

signed main(){

    int t;
    cin>>t;
    while(t--){
        slove();
    }
}

B. Qingshan Loves Strings

思维,构造

给一个数列a,元素只包含01,我们可以选择插入数组b 使得数列a的元素交替进行

请回答是否存在这样的构造

显然,当数列a中有两个连续的数的时候,我们才需要插入01

1、当连续的数是11,且数组b交替进行,且数组b两端是0 则yes

2、当连续的数是00,且数组b交替进行,且数组b的两端是1,则yes

所以步骤是:

1、判断数组a是否交替

2、特判数组a的长度为1的情况

3、求出数组a连续的地方,是11,还是00

4、判断数组b是否交替

5、当数组b两端为1

6、当数组b两端为0

#include<bits/stdc++.h>
using namespace std;

#define int long long
#define ll long long

void slove(){
   int n,m;
   cin>>n>>m;
   string s,t;
   cin>>s>>t;
   
   if(n==1){
       cout<<"YES"<<endl;
       return;
   }
   
   
   int jiji=0;
   int ouou=0;
   
   for(int i=0;i<n-1;i++){
       if(s[i]==s[i+1]){
           if(s[i]=='1')jiji++;
           else ouou++;
       }
   }
   if(jiji==0 and ouou==0){
       cout<<"YES"<<endl;
       return;
   }
   
   
   //检查t是否为好字符串
   for(int i=0;i<m-1;i++){
       if(t[i]==t[i+1]){
           cout<<"NO"<<endl;
           return;
       }
   }
   
   //检查t字符串首尾是否相同
   if(t[0]!=t[m-1]){
       cout<<"NO"<<endl;
       return;
   }
   
  
   
   
 //  cout<<jiji<<' '<<ouou<<endl;
   
   if(jiji!=0 and ouou!=0){
       cout<<"NO"<<endl;
       return;
   }
   else if(jiji!=0 and ouou==0){
       if(t[0]=='1'){
           cout<<"NO"<<endl;
           return;
       }
       else{
           cout<<"YES"<<endl;
           return;
       }
   }
   else if(jiji==0 and ouou!=0){
       if(t[0]=='1'){
           cout<<"YES"<<endl;
           return;
       }
       else{
           cout<<"NO"<<endl;
           return;
       }
   }
   else
   cout<<"YES"<<endl;
}

signed main(){

    int t;
    cin>>t;
    while(t--){
        slove();
    }
}

C. Qingshan Loves Strings 2

构造

和上一题不一样的是:

a i ≠ a k − i + 1   ( i = 1 , 2 , … , k ) ai≠a_{k−i+1} \ (i=1,2,…,k) ai=aki+1 (i=1,2,,k)

也就是对称的情况

所以,这个数组的长度必须是偶数,不能是奇数,因为奇数会多出一个自己和自己配对的情况。

我们利用双端队列模拟并记录左端点右端点即可:

用vector记录操作的序列:

当队首=队尾,删除队首队尾

l++,r–

当队首!=队尾

考虑插入“01”

当队首队尾为1,那么插在队首的前面

将l-1插入vector

r+=2

当队首队尾为0,那么插在队尾的前面

将r插入vector

r+=2

最后输出vector即可

#include<bits/stdc++.h>
using namespace std;
#define  ios ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr) 
#define int long long
#define ll long long
const int N=1e5;
int a[N];
void slove() {
  deque<char> q;
  int n;
  cin>>n;
  char t;
  for(int i=0;i<n;i++){
      cin>>t;
      q.push_back(t);
  }
  
  int cnt=0;
  int l=1,r=n;
  
  vector<int> ans;
  
  while(q.size()){
      if(cnt>300)break;
      
      char f=q.front();
      char b=q.back();
      if(f!=b){
          l++;
          r--;
          q.pop_back();
          q.pop_front();
      }
      else{
          if(f=='1' ){
              ans.push_back(l-1);
              q.push_front('1');
              q.push_front('0');
              r+=2;
          }
          else{
              ans.push_back(r);
              q.push_back('0');
              q.push_back('1');
              r+=2;
          }
          cnt++;
      }
  }
  
  if(cnt>300 and q.size())cout<<-1<<endl;
  else {
      cout<<cnt<<endl;
      for(auto i:ans)cout<<i<<' ';
      cout<<endl;
  }
  
  
}

signed main() {
  //  ios;
    int T;
    cin>>T;
    while(T--){
      slove();
    }
    
}

r+=2;
}
cnt++;
}
}

if(cnt>300 and q.size())cout<<-1<<endl;
else {
cout<<cnt<<endl;
for(auto i:ans)cout<<i<<’ ';
cout<<endl;
}

}

signed main() {
// ios;
int T;
cin>>T;
while(T–){
slove();
}

}


  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

louisdlee.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值