【AtCoder】ARC103

C - ////

爲了防止一些多餘的判斷,我選擇直接記錄每一個數的個數,而後枚舉第一個數,找第一個數以外第二個數改變最少的狀況下應該選什麼node

代碼

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
//#define ivorysi
#define MAXN 100005
typedef long long int64;
using namespace std;
template<class T>
void read(T &res) {
    res = 0;char c = getchar();T f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 + c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
        out(x / 10);
    }
    putchar('0' + x % 10);
}
int N,a[MAXN];
int L[MAXN],tot,ans,cnt1[MAXN],cnt2[MAXN],pre[MAXN],suf[MAXN];
void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) read(a[i]);
    for(int i = 1 ; i <= N ; i += 2) {
        cnt1[a[i]]++;
    }
    for(int i = 2 ; i <= N ; i += 2) {
        cnt2[a[i]]++;
    }
    for(int i = 1 ; i <= 100000 ; ++i) {
        pre[i] = max(pre[i - 1],cnt2[i]);
    }
    for(int i = 100000 ; i >= 1 ; --i) {
        suf[i] = max(suf[i + 1],cnt2[i]);
    }
    ans = N;
    for(int i = 1 ; i <= 100000 ; ++i) {
        ans = min(ans,N / 2 - cnt1[i] + N / 2 - max(pre[i - 1],suf[i + 1]));
    }
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

D - Robot Arms

103真是構造題大薈萃
若是全部的\(X_i + Y_i\)奇偶性不一樣,那麼顯然不行c++

那麼咱們考慮一下全部\(X_i + Y_i\)爲奇數的狀況spa

咱們找一個集合\({1,2,4,8...2^k}\)他們的總和大於\(|X_i| + |Y_i|\)的最大值code

咱們證實一下\({1,2,4,8..2^k}\)這個集合能夠達到全部\(|X_i| + |Y_i| <= 2^{k +1} - 1\)的全部\(X_i +Y_i\)和爲奇數的點遞歸

首先集合中只有\(1\)的時候,咱們能夠達到get

集合中有\({1,2}\)的時候,咱們經過向上下左右移動\(2\),是能夠達到距離原點距離爲\(1\)的位置的it

這樣遞歸證實,最後就是對的class

代碼

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
//#define ivorysi
#define MAXN 100005
typedef long long int64;
using namespace std;
template<class T>
void read(T &res) {
    res = 0;char c = getchar();T f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 + c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
        out(x / 10);
    }
    putchar('0' + x % 10);
}
int N;
int M = 0;
int64 op[35],sum,X[1005],Y[1005];
int64 dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
char s[1005][45];
const char *dir = "RDLU";
void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) {
        read(X[i]);read(Y[i]);
    }
    for(int i = 2 ; i <= N ; ++i) {
        if((abs(X[i]) + abs(Y[i])) % 2 != (abs(X[1]) + abs(Y[1])) % 2)  {
            puts("-1");return ;
        }
    }
    bool flag = 0;
    flag = ((abs(X[1]) + abs(Y[1])) % 2 == 0);
    if(flag) {op[++M] = 1;}
    for(int i = 30 ; i >= 0 ; --i) {op[++M] = 1 << i;sum += op[M];}
    pii st = mp(0,0);
    if(flag) st = mp(1,0);
    for(int i = 1 ; i <= N ; ++i) {
        if(flag) s[i][1] = 'R';
        pii p = st;
        int64 tmp = sum;
        for(int j = flag ? 2 : 1 ; j <= M ; ++j) {
            for(int k = 0 ; k <= 3 ; ++k) {
                int64 tx = p.fi + dx[k] * op[j],ty = p.se + dy[k] * op[j];
                int64 a = abs(tx - X[i]) + abs(ty - Y[i]);
                if(a <= tmp - op[j]) {
                    tmp -= op[j];
                    s[i][j] = dir[k];
                    p = mp(tx,ty);
                    break;
                }
            }
        }
    }
    out(M);enter;
    for(int i = 1 ; i <= M ; ++i) {
        out(op[i]);space;
    }
    enter;
    for(int i = 1 ; i <= N ; ++i) {
        for(int j = 1 ; j <= M ; ++j) {
            putchar(s[i][j]);
        }
        enter;
    }
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

E - Tr/ee

很容易發現1必須合法next

咱們想要某個大小的樹能夠被割出來
用一種節約節點的方式,能夠用上一個能夠拼出來的樹,接上一個根,不足的用大小爲1的葉子做爲補充sort

而後只要拼到n / 2,再直接加葉子拼到n便可

代碼

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
//#define ivorysi
#define MAXN 100005
typedef long long int64;
using namespace std;
template<class T>
void read(T &res) {
    res = 0;char c = getchar();T f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 + c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
        out(x / 10);
    }
    putchar('0' + x % 10);
}
int N,dp[100005];
char s[100005];
void add(int u,int v) {
    out(u);space;out(v);enter;
}
void Solve() {
    scanf("%s",s + 1);
    N = strlen(s + 1);
    for(int i = 1 ; i <= N ; ++i) dp[i] = s[i] - '0';
    if(!dp[1] || dp[N]) {puts("-1");return;}
    for(int i = 2 ; i <= N - 1 ; ++i) {
        if(dp[i]) {
            if(!dp[N - i]) {puts("-1");return;}
        }
    }
    int p = 1,rt = 1;
    for(int i = 2 ; i <= N / 2 ; ++i) {
        if(dp[i]) {
            add(rt,++p);rt = p;
            while(p < i) {add(rt,++p);}
        }
    }
    add(rt,++p);rt = p;
    while(p < N) {add(rt,++p);}
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

F - Distance Sums

Di最大的點必定是一個葉子,咱們找到Di - (n - 2)的點是連向它的點

而後以此類推,咱們能夠一邊從大到小枚舉D來算父親邊,同時維護每一個點的子樹大小

可是這必要但不充分,咱們能夠構造這棵樹出來時候從新算一遍D值來檢驗

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
//#define ivorysi
#define MAXN 100005
typedef long long int64;
using namespace std;
template<class T>
void read(T &res) {
    res = 0;char c = getchar();T f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 + c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
        out(x / 10);
    }
    putchar('0' + x % 10);
}
int N;
int64 D[MAXN],L[MAXN],dep[MAXN],C[MAXN];
int id[MAXN],s[MAXN],t[MAXN],tot,siz[MAXN];
 
struct node {
    int to,next;
}E[MAXN * 2];
int head[MAXN],sumE;
void add(int u,int v) {
    E[++sumE].to = v;
    E[sumE].next = head[u];
    head[u] = sumE;
}
bool cmp(int a,int b) {
    return D[a] < D[b];
}
void dfs(int u,int fa) {
    siz[u] = 1;
    for(int i = head[u] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(v != fa){
            dep[v] = dep[u] + 1;
            dfs(v,u);
            siz[u] += siz[v];
        }
    }
}
bool dfs1(int u,int fa) {
    if(C[u] != D[u]) return false;
    for(int i = head[u] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(v != fa) {
            C[v] = C[u] - siz[v] + N - siz[v];
            if(!dfs1(v,u)) return false;
        }
    }
    return true;
}
void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) {
        read(D[i]);id[i] = i;siz[i] = 1;
    }
    sort(id + 1,id + N + 1,cmp);
    for(int i = 1 ; i <= N ; ++i) L[i] = D[id[i]];
    for(int i = N ; i > 1 ; --i) {
        s[++tot] = id[i];
        int p = lower_bound(L + 1,L + i,L[i] + 2 * siz[s[tot]] - N) - L;
        if(L[p] != L[i] + 2 * siz[s[tot]] - N) {puts("-1");return;}
        t[tot] = id[p];
        siz[id[p]] += siz[id[i]];
    }
    for(int i = 1 ; i <= tot ; ++i) {add(s[i],t[i]);add(t[i],s[i]);}
    dfs(1,0);
    for(int i = 1 ; i <= N ; ++i) C[1] += dep[i];
    if(!dfs1(1,0)) {puts("-1");return;}
    for(int i = 1 ; i <= tot ; ++i) {
        out(s[i]);space;out(t[i]);enter;
    }
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}
相關文章
相關標籤/搜索