Codeforces Round #690 (Div. 3)

A:
按左右两边依次输出

#include<bits/stdc++.h>

using namespace std;

const int N = 1e5+10;

int a[N];
void solve()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    } 
    int l = 1, r = n;
    for (int i = 1; i <= n; i++)
        if (i % 2 == 0) 
        printf("%d ",a[r--]);
        else printf("%d ",a[l++]);

printf("\n");
}

int main()
{
    int T;
    scanf("%d",&T);
    for(int i=1;i<=T;i++)
    {
        solve();
    }
}

B:
因为只能删除一次所以满足条件的情况要没删除的段在2 0 2 0 这5个空隙里面插入的时候才一次删完

#include<bits/stdc++.h>

using namespace std;

const int N = 1e5+10;

string s;
void solve()
{
    int n;
    cin>>n;
    cin>>s;
    if(n<4)    
    {
        cout<<"NO"<<endl;
        return ;
    }
    if(s.substr(0,4)=="2020") 
    {
        cout<<"YES"<<endl;
        return ;
    }
    if(s.substr(n-4)=="2020") 
    {
        cout<<"YES"<<endl;
        return ;
    }
    if(s.substr(0,1)=="2"&&s.substr(n-3)=="020") 
    {
        cout<<"YES"<<endl;
        return ;
    }
    if(s.substr(0,2)=="20"&&s.substr(n-2)=="20") 
    {
        cout<<"YES"<<endl;
        return ;
    }
    if(s.substr(0,3)=="202"&&s.substr(n-1)=="0") 
    {
        cout<<"YES"<<endl;
        return ;
    }
    cout<<"NO"<<endl;




}

int main()
{
    int T;
    scanf("%d",&T);
    for(int i=1;i<=T;i++)
    {
        solve();
    }
}

C:因为不能重复又要求最小,所以尽量让低位是打数

#include<bits/stdc++.h>

using namespace std;

const int N = 1e5+10;

void solve()
{
    int n;
    cin>>n;
    string s;
    if(n<9) 
    {
        cout<<n<<endl;
        return ;
    }
    for(int i=9;i>=1;i--)
    {
        if(n>=i) 
        {
            s+=(i+'0');
            n-=i;
        }
    }
    reverse(s.begin(),s.end());
    if(n>0) cout<<"-1"<<endl;

    else cout<<s<<endl;

}

int main()
{
    int T;
    scanf("%d",&T);
    for(int i=1;i<=T;i++)
    {
        solve();
    }
}

D:
因为每次只能把自己加到与自己相邻的,相当于把一段相邻和,这样就可以转换成把数组分成k段并且这K段的和相等。
暴力就好了

#include<bits/stdc++.h>

using namespace std;

const int N = 1e6+10;
int a[N];
void solve()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        sum+=a[i];
    }
    int cnt=1;
    for(int i=1;i<=n;i++)
    {
        if(sum%i!=0) continue;
        int flag=0,sum1=0,cnt1=0;
        for(int j=1;j<=n;j++)
        {
            sum1+=a[j];
            if(sum1==sum/i) cnt1++,sum1=0;
            else if(sum1>sum/i) flag=1;
            if(flag==1) break;            
        }
        if(flag==1) continue;
        if(cnt1==i) cnt=i; 
    }
    cout<<n-cnt<<endl;



}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int T;
    cin>>T;
    for(int i=1;i<=T;i++)
    {
        solve();
    }
}

E:枚举每个点,找到比这个点+k的值大的然后pos--就是小于等于这个值得下标了,然后组合数计算一下就好了,注意init()不要放在solve()里面。。这样会T

#include<bits/stdc++.h>

using namespace std;

const int N = 3e5+10;
const int mod =1e9+7;
typedef long long ll;
ll a[N];
struct AC
{
    static const int maxn = 2e5+10;
    ll f[maxn];
    void init(int mod){ //预处理阶乘
        f[0] = 1;
        for(int i = 1;i<maxn;i++) f[i] = f[i-1]*i%mod;
    }
    ll ksm(ll a,ll b,ll mod){
        ll ans = 1;
        while(b){
            if(b&1) ans = ans*a%mod;
            a = a*a%mod;
            b>>=1;
        }
        return ans;
    }
    ll C_mod(ll n,ll m,ll mod){//组合数%mod
        return f[n] * ksm(f[m] * f[n-m]%mod,mod-2,mod)%mod;
    }
    ll lucas_mod(ll n,ll m,ll mod){
        return m? C_mod(n%mod,m%mod,mod) * lucas_mod(n/mod,m/mod,mod)%mod : 1;
    }
    ll A(ll n, ll r)//排列数
    {    
        ll sum = 1;
        for (int i = 0; i < r; i++)
            sum *= n-i;
        return sum;
    }
    ll C(ll n,ll K){ //组合数
        if(K>n) return 0;
        if(K > n-K) K = n-K;
        ll m = 1,s = 1;
        for(int i = 0;i<K;i++){
            m = m*(n-i);
            s = s*(i+1);
        }
        return m/s;
    }
}ac;
void solve()
{
    ac.init(mod);
    int n;
    ll m,k;
    scanf("%d%lld%lld",&n,&m,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
    }
    sort(a+1,a+n+1);
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
        ll x=a[i]+k;
        int pos=upper_bound(a+1,a+n+1,x)-a;
        pos--;
        if(pos-i>=m-1)
        sum+=ac.C_mod(pos-i,m-1,mod);
        sum%=mod;
    }
    printf("%lld\n",sum);


}

int main()
{
    int T;
    scanf("%d",&T);
    for(int i=1;i<=T;i++)
    {
        solve();
    }
}

F:树状数组离散化处理一下左右覆盖就好了

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e6+10;

ll tr[N];

ll lowbit(int x)
{
    return x&(-x);
}

void modify(int x,ll v)
{
    for(int i=x;i<=N;i+=lowbit(i)) tr[i]+=v;
}

ll query(int x)
{
    ll res=0;
    for(int i=x;i>=1;i-=lowbit(i)) res+=tr[i];
    return res;
}

int l[N], r[N], a[N], sum[N];
int cnt,n;


void solve()
{

        scanf("%d",&n);
        cnt = 0;
        for (int i = 1; i <= n; i++) 
        {
               scanf("%d%d",&l[i],&r[i]); 
               ++cnt;
            a[cnt] = l[i];
            ++cnt;
            a[cnt] = r[i];
        }
        int len=cnt*2;
        for (int i = 0; i<=len; i++)
        sum[i] = tr[i] = 0;
           sort(a + 1, a + 1 + cnt);
        cnt = unique(a + 1, a + 1 + cnt) - a - 1;

        for (int i = 1; i <= n; i++) {
           l[i] = lower_bound(a + 1, a + 1 + cnt, l[i]) - a;
            r[i] = lower_bound(a + 1, a + 1 + cnt, r[i]) - a;
            sum[l[i]]++, sum[r[i] + 1]--;
            modify(l[i], 1);
        }
        for (int i = 1; i <= cnt + 1; i++)
            sum[i] += sum[i - 1];
        ll ans = 0;
        for (int i = 1; i <= n; i++) {
            ans = max(sum[l[i]] + query(r[i]) - query(l[i]), ans);
        }
        printf("%d\n",n-ans);
}

int main()
{

    int t;
       scanf("%d",&t);
    for(int i=1;i<=t;i++) 
    {
       solve();
    }
    return 0;
}
全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务