《Codeforces Global Round 9》

C:

将序列排开。

a[1]  a[x]  a[x+1]  a[n].

可以发现,若满足a[1] < a[n].

那么对于a[x] > a[1]  和 a[x+1] < a[n] ,将肯定会存在一种情况满足。

然后就可以不断缩减区间数。最后变成a[1] , a[n].

所以当a[1] < a[n]时,就可以实现,否则当从左向右延伸最小值时,无法实现。

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 3e5+5;
const int M = 1e6+5;
const int Mod = 317000011;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
int a[N];
void run()
{
    int t;sd(t);
    while(t--)
    {
        int n;sd(n);
        for(int i = 1;i <= n;++i) sd(a[i]);
        if(a[1] < a[n] || n == 1) printf("YES\n");
        else printf("NO\n");
    }
}
int main()
{
    run();
    //system("pause");
    return 0;
}
View Code

 D:

可以将序列排成

1 2 3 4 ~ n 的最终序列。

若当前的最小值为0,那就将它替换为没有完成的任意一个位置。

当替换后,显然最小值就是没有完成的某一个值。所以此时只需要两步完成一个位置的配对。

若当前的最小值不为0,那就直接将最小值位置的值变为最小值。此时最需要一步完成一个位置的配对。

显然最多的替换次数也就是2*n,所以可以证明一定满足移动步数<=2*n。

这里用set来维护下最小的值,用优先队列爆内存了..。注意的是给已经配对的打上标记。

这样时间可以缩短不少。总复杂度t*n^2.

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 3e5+5;
const int M = 1e6+5;
const int Mod = 317000011;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
int a[1005],vis[1005],ok[1005];
void run()
{
    int t;sd(t);
    while(t--)
    {
        int n;sd(n);
        met0(ok);met0(vis);
        set<int> S;
        vector<int> vec;
        for(int i = 1;i <= n;++i) 
        {
            sd(a[i]),vis[a[i]]++;
            if(a[i] == i) ok[i] = 1;//不需要调整
        }
        for(int i = 0;i <= n;++i) if(vis[i] == 0) S.insert(i);
        int pos = 1;
        while(1)
        {
            int minn = *(S.begin()),f = 0;
            if(minn == 0)
            {
                for(int i = 1;i <= n;++i)
                {
                    if(!ok[i])
                    {
                        vec.pb(i);
                        f = 1;
                        int ma = a[i];
                        S.erase(S.begin());vis[0]++;
                        vis[ma]--;
                        if(vis[ma] == 0) S.insert(ma);
                        a[i] = 0;
                        break;
                    }
                }
                if(!f) break;
            }
            else
            {
                int ma = a[minn];
                S.erase(S.begin());
                vis[ma]--;
                if(vis[ma] == 0) S.insert(ma);
                a[minn] = minn;
                ok[minn] = 1;
                vec.pb(minn);
            }
        }
        pr(vec.size());
        for(int i = 0;i < vec.size();++i) printf("%d%c",vec[i],i == vec.size()-1 ? '\n' : ' ');
    }
}
int main()
{
    run();
    system("pause");
    return 0;
}
View Code

 

posted @ 2020-07-12 21:41  levill  阅读(117)  评论(0编辑  收藏  举报