【AtCoder】ARC095 CF Problem Solution

I can actually think of every question,
although not every question can be written correctly, I have debugged for a long time/facepalm

C - Many Medians

The median of the first N/2 numbers after sorting is the N/2 + 1th number after sorting, and the
rest of the medians are the N/2th numbers after sorting

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <cstring>
#include <string>
#include <ctime>
#include <algorithm>
#include <map>
#define MAXN 200005
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ba 823
#define mo 974711
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
int N;
int id[MAXN],X[MAXN],B[MAXN];
bool cmp(int a,int b) {
    return X[a] < X[b];
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    scanf("%d",&N);
    for(int i = 1 ; i <= N ; ++i) {
        scanf("%d",&X[i]);
        id[i] = i;
    }
    sort(id + 1,id + N + 1,cmp);
    int T = N / 2;
    for(int i = 1 ; i <= T ; ++i) {
        B[id[i]] = X[id[T + 1]];
    }
    for(int i = T + 1 ; i <= N ; ++i) {
        B[id[i]] = X[id[T]];
    }
    for(int i = 1 ; i <= N ; ++i) {
        printf("%d\n",B[i]);
    }
    return 0;
}

D - Binomial Coefficients

N is the largest, R is the closest to N/2

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <cstring>
#include <ctime>
#include <map>
#include <algorithm>
#include <cmath>
#define MAXN 200005
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ba 823
#define mo 974711
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
 
int N,A[100005];
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    ios::sync_with_stdio(false);
    scanf("%d",&N);
    for(int i = 1 ; i <= N ; ++i) scanf("%d",&A[i]);
    sort(A + 1,A + N + 1);
    printf("%d ",A[N]);
    double T = A[N] / 2.0;
    int t = 1;
    for(int i = 2 ; i <= N ; ++i) {
        if(fabs(A[i] - T) < fabs(A[t] - T)) t = i;
    }
    printf("%d\n",A[t]);
    return 0;
}

E - Symmetric Grid

In fact, the optimization I think does not need to be an extremely fast search . I
don’t know what the complexity is. Anyway,
it is found that two lines can match two lines. The character set is the same.
Two columns can match the characters that must be two columns. The set is the same.
We enumerate a row as the first row, and then find a row with the same character set as the last row, enumerate and match, and then each column is fixed, and finally find a match for the remaining N - 2 rows. The
matching condition is One row is read in the opposite direction, and the other row is read in the opposite direction.
Special judgment on odd-numbered rows and odd-numbered columns and H = 1, W = 1

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <cstring>
#include <ctime>
#include <map>
#include <algorithm>
#include <cmath>
#define MAXN 200005
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ba 823
#define ha 99994711
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
int H,W,St;
int Row[14][26],Col[14][26];
int matR[14][14],matC[14][14],idC[14],idR[14],mat[14];
bool vis[14],used[14];
char S[14][14];
void swapRow(int x,int y) {
    if(x == y) return;
    swap(idR[x],idR[y]);
    for(int i = 1 ; i <= W ; ++i) swap(S[x][i],S[y][i]);
}
void swapCol(int x,int y) {
    if(x == y) return;
    swap(idC[x],idC[y]);
    for(int i = 1 ; i <= H ; ++i) swap(S[i][x],S[i][y]);
}
bool match(int c) {
    if(c == 0) {
        memset(mat,0,sizeof(mat));
        int cnt = 0;
        for(int i = 2 ; i <= H - 1; ++i) {
            if(mat[i]) continue;
            for(int j = i + 1 ; j <= H - 1; ++j) {
                if(mat[j]) continue;
                bool f = 1;
                for(int k = 1 ; k <= W ; ++k) {
                    if(S[i][k] != S[j][W - k + 1]) {
                        f = 0;
                        break;
                    }
                }
                if(f) {mat[i] = j;mat[j] = i;break;}
            }
            if(!mat[i] && cnt < 1 && (H & 1)) {
                ++cnt;
                for(int k = 1 ; k <= W ; ++k) {
                    if(S[i][k] != S[i][W - k + 1]) return 0;
                }
                mat[i] = i;
            }
            else if(!mat[i]) return 0;
        }
        return 1;
    }
    if(c == W - c + 1) {
        for(int i = 1 ; i <= W ; ++i) {
            if(vis[i]) continue;
            if(S[1][i] == S[H][i]) {
                swapCol(i,c);
                vis[c] = 1;
                if(match(c - 1)) return 1;
                vis[c] = 0;
                swapCol(i,c);
            }
        }
    }
    else {
        for(int i = 1; i <= W; ++i) {
            if(vis[i]) continue;
            if(matC[idC[c]][idC[i]]) {
                if(S[1][c] == S[H][i] && S[1][i] == S[H][c]) {
                    vis[c] = vis[W - c + 1] = 1;
                    swapCol(i,W - c + 1);
                    if(match(c - 1)) return 1;
                    swapCol(i,W - c + 1);
                    vis[c] = vis[W - c + 1] = 0;
                }
            }
        }
    }
    return 0;
}
bool check() {
    for(int i = 2 ; i <= H ; ++i) {
        if(matR[idR[1]][idR[i]]) {
            if(used[idR[i]]) continue;
            swapRow(i,H);
            if(match((W & 1) ? W / 2 + 1 : W / 2)) return 1;
            swapRow(i,H);
        }
    }
    return 0;
}
void Solve() {
    scanf("%d%d",&H,&W);
    for(int i = 1 ; i <= H ; ++i) scanf("%s",S[i] + 1);
    for(int i = 1 ; i <= H ; ++i) {
        for(int j = 1 ; j <= W ; ++j) {
            Row[i][S[i][j] - 'a']++;
        }
    }
    for(int j = 1 ; j <= W ; ++j) {
        for(int i = 1 ; i <= H ; ++i) {
            Col[j][S[i][j] - 'a']++;
        }
    }
    if(H == 1) {
        int cnt = 0;
        for(int i = 0 ; i <= 25 ; ++i) {
            if(Row[1][i] & 1) ++cnt;
        }
        if(cnt > 1) puts("NO");
        else puts("YES");
        return;
    }
    else if(W == 1) {
        int cnt = 0;
        for(int i = 0 ; i <= 25 ; ++i) {
            if(Col[1][i] & 1) ++cnt;
        }
        if(cnt > 1) puts("NO");
        else puts("YES");
        return;
    }
    for(int i = 1 ; i <= H ; ++i) {
        for(int j = i ; j <= H ; ++j) {
            bool f = 1;
            for(int k = 0 ; k <= 25 ; ++k) {
                if(Row[i][k] != Row[j][k]) {f = 0;break;}
            }
            matR[i][j] = matR[j][i] = f;
            
        }
    }
    for(int i = 1 ; i <= W ; ++i) {
        for(int j = i ; j <= W ; ++j) {
            bool f = 1;
            for(int k = 0 ; k <= 25 ; ++k) {
                if(Col[i][k] != Col[j][k]) {f = 0;break;}
            }
            matC[i][j] = matC[j][i] = f;
        }
    }
    for(int i = 1 ; i <= H ; ++i) idR[i] = i;
    for(int i = 1 ; i <= W ; ++i) idC[i] = i;
    for(int i = 1 ; i <= H ; ++i) {
        used[i] = 1;
        swapRow(i,1);
        if(check()) {puts("YES");return;}
        swapRow(i,1);
    }
    
    puts("NO");
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

F - Permutation Tree

There is only one legal chain with long leaves
. Delete the leaves and find a chain. If there are leaves at both ends of the chain, they will grow out.
Then use an array to record the number of leaves at each point on the chain,
and then compare them from left to right. If the left side is smaller than the right side, jump out, if the right side is smaller than the left side, flip and jump out
. When constructing, a point sequence with k leaves is p + 1, p + 2...p + k, p.
The code ability is not good, and I kneeled three times. QAQ

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <cstring>
#include <ctime>
#include <map>
#include <algorithm>
#include <cmath>
#define MAXN 100005
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ba 823
#define ha 99994711
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
int N;
struct node {
    int to,next;
}E[MAXN * 2];
int sumE,head[MAXN],ind[MAXN],fa[MAXN],st,ed,D[MAXN];
int line[MAXN],tot;
void add(int u,int v) {
    E[++sumE].to = v;
    E[sumE].next = head[u];
    head[u] = sumE;
}
void dfs(int u) {
    ed = u;
    for(int i = head[u] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(v != fa[u] && ind[v] != -1) {
            fa[v] = u;
            dfs(v);
        }
    }
}
void Solve() {
    scanf("%d",&N);
    int u,v;
    for(int i = 1 ; i < N ; ++i) {
        scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
        ind[u]++;ind[v]++;
    }
    if(N == 2) {
        puts("1 2");return;
    }
    memcpy(D,ind,sizeof(ind));
    for(int i = 1 ; i <= N ; ++i) {
        if(ind[i] == 1) {
            for(int j = head[i] ; j ; j = E[j].next) {
                int v = E[j].to;
                D[v]--;
            }
            D[i] = -1;
        }
    }
    memcpy(ind,D,sizeof(ind));
    for(int i = 1 ; i <= N ; ++i) {
        if(ind[i] > 2) {puts("-1");return;}
    }
    for(int i = 1 ; i <= N ; ++i) {
        if(ind[i] == 1) {st = i;dfs(st);break;}
    }
    if(!st) {
        for(int i = 1 ; i <= N ; ++i) {
            if(ind[i] == 0) {st = i;dfs(st);break;}
        }
    }
    for(int i = head[ed] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(v != fa[ed]) {
            fa[v] = ed;
            ed = v;
            break;
        }
    }
 
    for(int i = head[st] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(!fa[v]) {
            fa[st] = v;
            st = v;
            break;
        }
    }
    ind[ed] = ind[st] = 1;
    int p = ed;
    while(p) {
        ++tot;
        for(int i = head[p] ; i ; i = E[i].next) {
            int v = E[i].to;
            if(ind[v] == -1) {
                line[tot]++;
            }
        }
        p = fa[p];
    }
    int L = 1,R = tot;
    while(L <= tot && R >= 1) {
        if(line[L] < line[R]) break;
        else if(line[L] > line[R]) {reverse(line + 1,line + tot + 1);break;}
        ++L;--R;
    }
    p = 2;
    printf("%d",1);
    for(int i = 2 ; i <= tot ; ++i) {
        for(int j = p + 1 ; j <= p + line[i] ; ++j) {
            printf(" %d",j);
        }
        printf(" %d",p);
        p = p + line[i] + 1;
    }
    putchar('\n');
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325290230&siteId=291194637