• 【AtCoder】ARC095 C-F题解


    我居然每道题都能想出来
    虽然不是每道题都能写对,debug了很久/facepalm

    C - Many Medians

    排序后前N/2个数的中位数时排序后第N/2 + 1的数
    其余的中位数都是排序后第N / 2的数

    #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
    ",B[i]);
        }
        return 0;
    }
    

    D - Binomial Coefficients

    N取最大的,R取最接近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
    ",A[t]);
        return 0;
    }
    

    E - Symmetric Grid

    事实上我想的优化不用也是个奇快无比的搜索
    复杂度是啥不知道,反正1ms
    发现两行能匹配上一定是两行的字符集是相同的
    两列能匹配上一定是两列的字符集相同
    我们枚举某行作为第一行,然后找它字符集相同的一行作为最后一行,枚举匹配,然后每一列都固定了,最后给剩下的N - 2行找匹配就行
    匹配条件是某一行正着读等于另一行反着读
    特判奇数行奇数列和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

    合法的只有一条链上长叶子
    把叶子删掉,搜出一条链,链的两端如果有叶子就长出来
    然后用一个数组记录链上每个点长的叶子的个数
    然后从左右开始比较,如果左边小于右边就跳出,如果右边小于左边就翻转后跳出
    构造的时候一个长了k个叶子的点排序就是 p + 1,p + 2...p + k, p
    代码能力不行,跪了三次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('
    ');
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
        return 0;
    }
    
  • 相关阅读:
    StructureMap经典的IoC/DI容器
    移植的7zip到Vxworks 取名vx7zip
    试验Boost在Vxworks上的应用日记 三
    Log4cpp 崩溃
    试验Boost在Vxworks上的应用日记 一
    Vx7zip改进
    GoAhead 2.5 Web Server 网页ROM化的改进
    试验Boost在Vxworks上的应用日记 二
    原来CoreBluetooth 只支持Bluetooth Low Energy
    可变长结构体
  • 原文地址:https://www.cnblogs.com/ivorysi/p/8991940.html
Copyright © 2020-2023  润新知