AtCoder Regular Contest 095


C - Many Medians

题意:

给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数。

\(n\le 200000\)

分析:

发现题目范围支持\(nlogn\)做法。

我们可以对这些数字建立一棵平衡树,先全加进去,再一边删除一边find一边再加,非常容易想到的解法,但是真要这么写估计排名高不到哪里去。

考虑删除一个数之后中位数的情况,明显只有两种,一种是你删除的数小于等于中位数,还一种是大于中位数,那么可以先排序找出中位数,然后遍历,判断每个数和中位数的大小关系,可以得出正确结果。

#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+10;
int a[MAXN],b[MAXN];
int main()
{
int n;
while(cin>>n){
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+n+1);
int mid=n/2;
for(int i=1;i<=n;i++){
if(a[i]<=b[mid]) cout<<b[mid+1]<<endl;
else cout<<b[mid]<<endl;
}
}
}

D - Binomial Coefficients

题意:

给出n个数,从中选取两个数\(a_{i},a_{j}\),且\(a_i\ge a_j\),使\(C_{a_i}^{a_j}\)最大。

\(n\le 100000\)

分析:

观察题目范围,我们可以用\(nlogn\)的复杂度解决问题。

考虑组合数的几个式子:

1.\(C_n^k\ge C_{n-1}^k\)

2.\(C_n^k\ge C_n^{k-1}\)

所以直接找到最大的数\(n\),然后找到一个最接近于\(n/2\)的数\(k\)就一定是最优的。

发现可以使用平衡树,首先直接全部插入splay中,然后取得最大的,把\(n/2\)插入,求前驱后继,然后比较一下就行了,但是这么写明显不会有好的排名。

可以在输入时先找到最大的数,然后再遍历一遍数组,容易找出结果。

#include <bits/stdc++.h>
using namespace std;
int a[1000007],n,id;
int main()
{
cin>>n;
int maxx=-1;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]>maxx){
maxx=a[i];
id=i;
}
}
int mid=maxx/2+(maxx%2==1?1:0),ans,cnt=1999999999;
for(int i=1;i<=n;i++){
if(i==id) continue;
if(abs(mid-a[i])<=cnt){
cnt=abs(mid-a[i]);
ans=a[i];
}
}
cout<<maxx<<" "<<ans;
}

E - Symmetric Grid

题意:

给出一个由字符组成的矩阵,可以任意交换某两行或者某两列,问是否能将这个矩形交换成对称的。

分析:

思路非常清晰,代码比较复杂。

先判断所有行的最终排列,然后在这个基础上check这时的所有列能否满足两两匹配,如果不能匹配的少于两个的话就可能是一个可行解。

提出另一种解法:可以直接看出每行的各字符数不会发生任何变化,每列的各字符数不会发生任何变化。并且如果找到一组可行解,可以随便配对行列的排列顺序,保证得出的还是一个可行解。

那么是否可以直接把每行的字符排序之后的字符串扔到一个map里面,然后判断是否能配对,同样我们对列也这么做,貌似可以做到极其优秀的复杂度,不过笔者并没有尝试。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN=30;
char st[MAXN][MAXN];
int sp[MAXN],ans,used[MAXN];
int n,m;
bool check()
{
memset(used,0,sizeof(used));
for(int i=0;i<m;i++){
if(used[i]) continue;
for(int j=0;j<m;j++){
bool vis=1;
if(i==j||used[j]) continue;
for(int k=0;k<n;k++){
if(st[k][i]==st[sp[k]][j]) continue;
vis=0;
break;
}
if(vis){
used[i]=used[j]=1;
break;
}
}
}
int cnt=0,pos=-1;
for(int i=0;i<m;i++)
if(!used[i]) cnt++,pos=i;
if(cnt>=2||(cnt&&(m%2==0))) return 0;
if(cnt==1)
for(int i=0;i<n;i++)
if(st[i][pos]!=st[sp[i]][pos]) return 0;
return 1;
}
void dfs(int u,int flag)
{
if(u==(n+1)>>1){
if(check()) ans=1;
return;
}
if(ans==1) return;
for(int i=u;i<n;i++){
if(sp[i]==-1){
for(int j=i+1;j<n;j++){
if(sp[j]==-1){
sp[i]=j;sp[j]=i;
dfs(u+1,flag);
sp[i]=sp[j]=-1;
}
}
if(flag){
sp[i]=i;
dfs(u+1,0);
sp[i]=-1;
}
}
}
}
int main()
{
while(cin>>n>>m){
memset(sp,-1,sizeof(sp));
ans=0;
for(int i=0;i<n;i++) scanf("%s",st[i]);
if(n&1) dfs(0,1);
else dfs(0,0);
if(ans) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}

F - Permutation Tree

题意:

给你一个序列\((p_1,p_2,…,p_n)对于每一个结点\)(1,2,…,n)$,两种操作

1.如果\(p_i=1\),无需任何操作

2.如果\(p_i≠1\),找出最大的j,满足pj<pi,则连接结点i和结点j.

通过序列\((p_1,p_2,…,p_n)\)可以唯一的构造一棵树。

题目给你n表示有n个结点,然后n-1条边构造一棵树。问是否可以输出一个\((p_1,p_2,…,p_n)\) 序列,通过这个序列构造的树和题目给出的树同构,可以的话,输出满足这个条件的最小字典序的序列。无解的话输出-1。

分析:

先不分析了。

#include <bits/stdc++.h>
using namespace std;
const int MAXN=4e5+7;
int head[MAXN],vis[MAXN],size[MAXN],dep[MAXN],nod[MAXN];
struct po
{
int nxt,to,from;
}edge[MAXN];
int n,m,num,cnt,ans=1,s,t,flag=1;
inline void add_edge(int from,int to)
{
edge[++num].nxt=head[from];
edge[num].from=from;
edge[num].to=to;
head[from]=num;
}
inline int bfs(int S)
{
memset(vis,0,sizeof(vis));
queue<int> q;
q.push(S);
vis[S]=1;
int u;
while(!q.empty()){
u=q.front(); q.pop();
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
return u;
}
void dfs(int u)
{
if(!flag) return;
int tp=0;
vis[u]=1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(!vis[v]){
dfs(v);
dep[u]=max(dep[u],dep[v]);
if(dep[v]>1) tp++;
if(v!=t&&dep[v]==1) size[u]++;
}
}
dep[u]++;
if(tp>=2){
flag=0;
return;
}
if(u!=s&&u!=t&&dep[u]>=2)
nod[cnt++]=size[u];
}
void out(int u)
{
int tt=ans;
vis[u]=1;
if(size[u]>0) for(int i=1;i<=size[u];i++) cout<<++ans<<" ";
printf("%d%c", tt,u==t?'\n':' ');
ans++;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==t||v==s||dep[v]>1){
if(!vis[v]) out(v);
}
}
}
int main()
{
cin>>n;
m=n-1;
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
add_edge(u,v);
add_edge(v,u);
}
t=bfs(1);s=bfs(t);
memset(vis,0,sizeof(vis));
dfs(s); reverse(nod,nod+cnt);
for(int i=0;i<cnt;i++){
if(nod[i]<nod[cnt-i-1]) break;
else if(nod[i]>nod[cnt-i-1]){
swap(s,t);
break;
}
}
memset(vis,0,sizeof(vis));
if(!flag) cout<<"-1";
else out(s);
}

AtCoder Regular Contest 095的更多相关文章

  1. 【枚举】AtCoder Regular Contest 095 C - Symmetric Grid

    题意:给你一个H*W的字符矩阵,一次操作可以任意将两行或者两列交换.问你是否能通过任意多次操作,使得其变为对称矩阵.对称的含义是:对于任何格子A(i,j),其都等于A(H-i+1,W-j+1). 显然 ...

  2. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  3. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  4. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  5. AtCoder Regular Contest 093

    AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...

  6. AtCoder Regular Contest 094

    AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...

  7. AtCoder Regular Contest 102

    AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...

  8. AtCoder Regular Contest 096

    AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...

  9. AtCoder Regular Contest 097

    AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...

随机推荐

  1. python 之 内置函数大全

    一.罗列全部的内置函数 戳:https://docs.python.org/2/library/functions.html 二.range.xrange(迭代器) 无论是range()还是xrang ...

  2. 将坐标转化为与X轴正半轴夹角模板

    //还需加PI 和 mabs 函数 double chg(double x,double y) { double tmps; )<1e-) { ) tmps=90.0; else tmps=27 ...

  3. vue学习之旅:入门

    首先利用脚手架vue cli搭建vue环境 引入 vue <script src="https://unpkg.com/vue/dist/vue.js"></sc ...

  4. :nth- 从1开始计数,其他如:eq()、 index()从0开始计数

    因为jQuery的实现:nth-是严格来自CSS规范,n值是“1-indexed”,也就是说,从1开始计数. 对于所有其他选择器表达式比如:eq() 或 :even ,jQuery遵循JavaScri ...

  5. Django开发流程

    1.创建Django工程 django-admin startproject pro1 2.settings.py配置中文和时区,和在pro1根目录下创建一个'static'目录,并在settings ...

  6. paper reading:gaze tracking

    https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Krafka_Eye_Tracking_for_CVPR_2016_ ...

  7. 编译安装cmake3

    编译安装cmake3 ubuntu 14 的系统默认安装的是cmake2.7,apt-get upgrade之后也还是cmake2.7,而很多软件如今需要3及以上的版本来进行cmake编译(如caff ...

  8. 001-es6变量声明、解构赋值、解构赋值主要用途

    一.基本语法 1.1.声明变量的六种方法 参看地址:http://es6.ruanyifeng.com/#docs/let let:局部变量,块级作用域,声明前使用报错 var:全局变量,声明前使用 ...

  9. 009-JDK可视化监控工具-JConsole

    Console工具在JDK/bin目录下,启动JConsole后,将自动搜索本机运行的jvm进程,不需要jps命令来查询指定.双击其中一个jvm进程即可开始监控,也可使用“远程进程”来连接远程服务器. ...

  10. CAS单点登录实践(spring cas client配置)

    前言: 最近的项目需要将多个站点统一登录,查阅了资料Jasig cas(Central Authentication Service)(官方站点:http://www.jasig.org/cas)使用 ...