《Codeforces Round #696 (Div. 2)》

A:显然保证长度不变是最大的,然后交换1,0,2即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e5 + 5;
const int M = 3e5 + 5;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e18
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

int main()
{
    int ca;ca = read();
    while(ca--){
        int n;n = read();
        string s;cin >> s;
        string ans = "1";
        int pre;
        for(int i = 0;i < s.size();++i){
            if(i == 0){
                if(s[i] == '0') pre = 1;
                else pre = 2;
            }
            else{
                if(pre == 1){
                    if(s[i] == '0') ans += "0",pre = 0;
                    else ans += "1",pre = 2;
                }
                else if(pre == 0){
                    ans += "1";
                    if(s[i] == '0') pre = 1;
                    else pre = 2;
                }
                else{//pre = 2
                    if(s[i] == '0') ans += "1",pre = 1;
                    else ans += "0",pre = 1;
                }
            }
        }
        cout << ans << "\n";
    }
//    system("pause");
    return 0;
}
View Code

B:对于一个只有四个因子的数,排除1和本身,那么另外两个肯定是要素数。(不然就有因子的因子)

所以我们只需要找到这两个素数即可。二分找到第一个>= 1 + d的素数,第二个就是 >= 这个素数 + d的素数。

至于和最后一个数的差距,肯定 >= d,因为数增长到了很大。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e5 + 5;
const int M = 3e5 + 5;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e18
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

bool vis[N];
int prime[N],tot = 0;
void init(){
    for(int i = 2;i < N;++i){
        if(!vis[i]){
            prime[++tot] = i;
        }
        for(int j = 1;j <= tot && prime[j] * i < N;++j){
            vis[prime[j] * i] = 1;
            if(i % prime[j] == 0) break;
        }
    }
}
int main()
{
    init();
    int ca;ca = read();
    while(ca--){
        int d;d = read();
        int L = lower_bound(prime + 1,prime + tot + 1,1 + d) - prime;
        L = prime[L];
        int r = lower_bound(prime + 1,prime + tot + 1,L + d) - prime;
        r = prime[r];
        printf("%lld\n",1LL * L * r);
    }
    //system("pause");
    return 0;
}
View Code

C:显然可以发现,每次选出的一个数都是剩下的数中的最大的数。

那么第一次选的肯定是最大的数和另一个数。一开始就卡在这里了。

但是其实只要另一个数也固定了,剩下的数就是剩下的最大 和 上一轮的最大 - 剩下的最大。

即剩下的选定局面就固定了,所以我们只需要去枚举和最大的数一开始组成的数对即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e6 + 5;
const int M = 3e5 + 5;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e18
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

int a[2005];
int main()
{
    int ca;ca = read();
    while(ca--){
        int n;n = read();
        map<int,int> mp;
        priority_queue<int,vector<int>,less<int> > Q;
        for(int i = 1;i <= 2 * n;++i) {
            a[i] = read();
            mp[a[i]]++;
            Q.push(a[i]);
        }
        sort(a + 1,a + 2 * n + 1);
        vector<pii> ans;
        int tag = 0;
        for(int i = 1;i < 2 * n;++i){
            ans.clear();
            ans.push_back(pii{a[i],a[2 * n]});
            map<int,int> ma = mp;
            priority_queue<int,vector<int>,less<int> > T = Q;
            T.pop();
            ma[a[i]]--;
            ma[a[2 * n]]--;
            int pre = a[2 * n],f = 0;
            for(int j = 2;j <= n;++j){
                while(ma[T.top()] == 0) T.pop();
                int tmp = T.top();
                T.pop();
                ma[tmp]--;
                int ta = pre - tmp;
                if(ma[ta] == 0){
                    f = 1;
                    break;
                }
                ma[ta]--;
                ans.push_back(pii{tmp,ta});
                pre = tmp;
            }
            if(f == 0){
                tag = 1;
                break;
            }
        }
        if(tag){
            printf("YES\n");
            printf("%d\n",ans[0].first + ans[0].second);
            for(auto v : ans) printf("%d %d\n",v.first,v.second);
        }
        else printf("NO\n");
    }
    //system("pause");
    return 0;
}
View Code

D:这题非常优秀。

首先考虑,如果不换位,那么检查是否能的话,就是贪心从左往右,或者从右往左(两者等价)。

如果中间 < 0,或者最后 != 0,就说明不可以。

那么加入换位之后,对于换位的操作,即,i位置如果不满足,那么显然要换i位置。

也就是说,不满足的位置不能超过1处。这样的话肯定无解。

然后我们可以发现,交换i位置 和 i + 1位置,对左右都1 ~ L - 1 和 i + 2 ~ n的合并没有影响。

如果我们考虑普通地交换i 和 i + 1,然后再去检查,那么复杂度为n ^ 2。

所以我们只需要预处理出前后和并剩余的石子然后O(1)检查即可。

即L[i - 1],a[i],a[i + 1],r[i + 2]。

为什么只需要考虑交换i 和 i + 1位置,因为如果不合法,显然是i的左边或者右边不合法。

此时其他的都合法,因为不合法的位置不超过1处,那么此时交换相邻的就不会让其他合法的不合法,且是唯一交换法。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 3e5 + 5;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e18
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

LL a[N],n,b[N],L[N],r[N];
bool check(){
    for(int i = 1;i <= n;++i) b[i] = a[i];
    for(int i = 2;i <= n;++i){
        b[i] -= b[i - 1];
        if(b[i] < 0) return false;
    }
    if(b[n] != 0) return false;
    return true;
}
int main()
{
    int ca;ca = read();
    while(ca--){
        n = read();
        memset(L,0,sizeof(L));
        memset(r,0,sizeof(r));
        for(int i = 1;i <= n;++i) a[i] = read();
        L[1] = a[1],r[n] = a[n];
        for(int i = 2;i <= n;++i){
            if(a[i] < L[i - 1]) L[i] = INF;
            else L[i] = a[i] - L[i - 1];
        }
        for(int i = n - 1;i >= 1;--i){
            if(a[i] < r[i + 1]) r[i] = INF;
            else r[i] = a[i] - r[i + 1];
        }
        if(check()) printf("YES\n");
        else{
            bool f = 0;
            swap(a[1],a[2]);
            if(check()) f = 1;
            swap(a[1],a[2]);
            swap(a[n - 1],a[n]);
            if(check()) f = 1;
            swap(a[n - 1],a[n]);
            for(int i = 2;i <= n - 2;++i){
                if(L[i - 1] != INF && r[i + 2] != INF && L[i - 1] <= a[i + 1] && r[i + 2] <= a[i] && a[i + 1] - L[i - 1] == a[i] - r[i + 2]){
                    f = 1;
                    break;
                }
            }   
            printf("%s\n",f ? "YES" : "NO");
        }
    }
    system("pause");
    return 0;
}
View Code

 

posted @ 2021-01-31 16:31  levill  阅读(74)  评论(0编辑  收藏  举报