Codeforces Round #669 (Div. 2)

那天晚上和同学打球打的有点晚,结果就鸽了,现在来补一下

A - Ahahahahahahahaha

直接看原数组中0的个数cnt0和1的个数cnt1,谁多留谁即可,注意留1的时候要留偶数个。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1010;
int a[N];
int n;
int main()
{
    IO;
    int T=1;
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        int cnt0=0,cnt1=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]) cnt1++;
            else cnt0++;
        }
        if(cnt1<=n/2)
        {
            cout<<cnt0<<'\n';
            for(int i=1;i<=cnt0;i++) cout<<0<<' ';
            cout<<'\n';
        }
        else
        {
            if(cnt1&1) cnt1--;
            cout<<cnt1<<'\n';
            for(int i=1;i<=cnt1;i++) cout<<1<<' ';
            cout<<'\n';
        }
    }
    return 0;
}

B - Big Vova

直接暴力,从第一位开始每次选一个目前使c[i]最大的数即可,维护d使之为 d = g c d ( b 1 , b 2 … b i ) d=gcd(b_1,b_2\dots b_i) d=gcd(b1,b2bi)
时间复杂度 O ( n 2 l o g n ) O(n^2logn) O(n2logn)

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1010;
int a[N],b[N],n;
int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}
int main()
{
    IO;
    int T=1;
    cin>>T;
    while(T--)
    {
        cin>>n;
        int d=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            d=max(a[i],d);
        }
        for(int i=1;i<=n;i++)
        {
            int mx=0;
            int p=-1;
            for(int j=1;j<=n;j++)
            {
                if(a[j]==0) continue;//之前选过
                if(mx<gcd(d,a[j]))
                {
                    mx=gcd(d,a[j]);
                    p=j;
                }
            }
            b[i]=a[p];
            d=gcd(d,b[i]);
            a[p]=0;
        }
        for(int i=1;i<=n;i++) cout<<b[i]<<' ';
        cout<<'\n';
    }
    return 0;
}

C - Chocolate Bunny

交互题,第一次做什么东西啊
每次选择没有确定的两个位置i,j,询问i、jj、i。分析可知这样一定能确定一个位置的数。总询问次数为 2 n − 2 2n-2 2n2次,即可原序列。
如果 a i > a j a_i>a_j ai>aj,已知 a i % a j = x a_i \%a_j= x ai%aj=x a j % a i = y a_j \%a_i= y aj%ai=y,分析可知 a [ j ] = y a[j]=y a[j]=y即确定了一个位置的数。
如果 a i < a j a_i<a_j ai<aj,已知 a i % a j = x a_i \%a_j= x ai%aj=x a j % a i = y a_j \%a_i= y aj%ai=y,分析可知 a [ i ] = x a[i]=x a[i]=x也能能够确定一个位置的数。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=10010;
int a[N],n;
bool st[N];
int main()
{
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        cin>>n;
        int x,y,now=1;
        for(int i=2;i<=n;i++)
        {
            cout<<"? "<<now<<' '<<i<<'\n';cout.flush();cin>>x;
            cout<<"? "<<i<<' '<<now<<'\n';cout.flush();cin>>y;
            if(x>y)
            {
                a[now]=x;
                st[x]=1;
                now=i;
            }
            else
            {
                a[i]=y;
                st[y]=1;
            }
        }
        for(int i=1;i<=n;i++)
            if(!st[i]) a[now]=i;
        cout<<"! ";
        for(int i=1;i<=n;i++) cout<<a[i]<<' ';
        cout<<'\n';
        
    }
    return 0;
}

D - Discrete Centrifugal Jumps

f [ i ] = m i n ( f [ i ] , f [ k ] + 1 ) f[i]=min(f[i],f[k]+1) f[i]=min(f[i],f[k]+1) 对于 h [ k + 1 … i − 1 ] h[k+1\dots i-1] h[k+1i1]满足题目条件即可

// O(n^2)
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=300010;
int h[N],n;
int f[N];
int main()
{
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>h[i];
        memset(f,0x3f,sizeof f);
        f[1]=0;
        for(int i=1;i<=n;i++)
        {
            int maxh=0,minh=0x3f3f3f3f;
            for(int j=i-1;j;j--)
            {
                if(minh>max(h[i],h[j])||maxh<min(h[i],h[j]))
                    f[i]=min(f[i],f[j]+1);
                minh=min(minh,h[j]);
                maxh=max(maxh,h[j]);
            }
        }
        cout<<f[n]<<endl;
    }
    return 0;
}

尝试采用单调栈维护一个单调序列不妨先考虑一种情况即 m a x ( h i + 1 , … , h j − 1 ) < m i n ( h i , h j ) max(h_{i+1},…,h_{j−1})<min(h_i,h_j) max(hi+1,,hj1)<min(hi,hj),维护严格单调上升的序列,对于第 i i i个山峰考虑合法转移:对于单调栈中的元素如果第一个大于 h i h_i hi中的下标是 p o s pos pos那么 f [ p o s − 1 ] … f [ t t ] f[pos-1]\dots f[tt] f[pos1]f[tt]都可以更新 f [ i ] f[i] f[i],在维护有序栈的同时更新不断更新答案即可

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=300010;
int h[N],n;
int q1[N],tt1;
int q2[N],tt2;
int f[N];
int main()
{
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>h[i];
        q1[++tt1]=1,q2[++tt2]=1;
        for(int i=2;i<=n;i++)
        {
            f[i]=f[i-1]+1;
            while(tt1&&h[q1[tt1]]>h[i])
                f[i]=min(f[q1[tt1--]]+1,f[i]);
            if(tt1) f[i]=min(f[q1[tt1]]+1,f[i]);
            while(tt1&&h[q1[tt1]]==h[i]) tt1--;
            q1[++tt1]=i;
            
            while(tt2&&h[q2[tt2]]<h[i])
                f[i]=min(f[q2[tt2--]]+1,f[i]);
            if(tt2) f[i]=min(f[q2[tt2]]+1,f[i]);
            while(tt2&&h[q2[tt2]]==h[i]) tt2--;
            q2[++tt2]=i;
        }
        cout<<f[n]<<'\n';
    }
    return 0;
}

要加油哦~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值