【AtCoder】ARC103
C - ////
为了防止一些多余的判断,我选择直接记录每个数的个数,然后枚举第一个数,找第一个数之外第二个数改变最少的情况下应该选什么
代码
#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\)奇偶性不同,那么显然不行
那么我们考虑一下所有\(X_i + Y_i\)为奇数的情况
我们找一个集合\({1,2,4,8...2^k}\)他们的总和大于\(|X_i| + |Y_i|\)的最大值
我们证明一下\({1,2,4,8..2^k}\)这个集合可以达到所有\(|X_i| + |Y_i| <= 2^{k +1} - 1\)的所有\(X_i +Y_i\)和为奇数的点
首先集合中只有\(1\)的时候,我们可以达到
集合中有\({1,2}\)的时候,我们通过向上下左右移动\(2\),是可以达到距离原点距离为\(1\)的位置的
这样递归证明,最后就是对的
代码
#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必须合法
我们想要某个大小的树可以被割出来
用一种节约节点的方式,可以用上一个可以拼出来的树,接上一个根,不足的用大小为1的叶子作为补充
然后只要拼到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;
}
【AtCoder】ARC103的更多相关文章
- 【AtCoder】ARC092 D - Two Sequences
[题目]AtCoder Regular Contest 092 D - Two Sequences [题意]给定n个数的数组A和数组B,求所有A[i]+B[j]的异或和(1<=i,j<=n ...
- 【Atcoder】CODE FESTIVAL 2017 qual A D - Four Coloring
[题意]给定h,w,d,要求构造矩阵h*w满足任意两个曼哈顿距离为d的点都不同色,染四色. [算法]结论+矩阵变换 [题解] 曼哈顿距离是一个立着的正方形,不方便处理.d=|xi-xj|+|yi-yj ...
- 【AtCoder】ARC 081 E - Don't Be a Subsequence
[题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...
- 【AtCoder】AGC022 F - Leftmost Ball 计数DP
[题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...
- 【AtCoder】AGC005 F - Many Easy Problems 排列组合+NTT
[题目]F - Many Easy Problems [题意]给定n个点的树,定义S为大小为k的点集,则f(S)为最小的包含点集S的连通块大小,求k=1~n时的所有点集f(S)的和取模92484403 ...
- 【AtCoder】ARC067 F - Yakiniku Restaurants 单调栈+矩阵差分
[题目]F - Yakiniku Restaurants [题意]给定n和m,有n个饭店和m张票,给出Ai表示从饭店i到i+1的距离,给出矩阵B(i,j)表示在第i家饭店使用票j的收益,求任选起点和终 ...
- 【AtCoder】ARC095 E - Symmetric Grid 模拟
[题目]E - Symmetric Grid [题意]给定n*m的小写字母矩阵,求是否能通过若干行互换和列互换使得矩阵中心对称.n,m<=12. [算法]模拟 [题解]首先行列操作独立,如果已确 ...
- 【Atcoder】AGC022 C - Remainder Game 搜索
[题目]C - Remainder Game [题意]给定n个数字的序列A,每次可以选择一个数字k并选择一些数字对k取模,花费2^k的代价.要求最终变成序列B,求最小代价或无解.n<=50,0& ...
- 【Atcoder】AGC 020 B - Ice Rink Game 递推
[题意]n个人进行游戏,每轮只保留最大的a[i]倍数的人,最后一轮过后剩余2人,求最小和最大的n,或-1.n<=10^5. [算法]递推||二分 [题解]令L(i),R(i)表示第i轮过后的最小 ...
随机推荐
- (转)Java随机数
1 随机数的三种产生方式 本章先讲解Java随机数的几种产生方式,然后通过示例对其进行演示. 广义上讲,Java中的随机数的有三种产生方式: (01). 通过System.currentTimeMil ...
- python数字转换为字符串的两种方式
主要包括两种形式进行转换: 第一种是str(),将值转换为用户便于阅读的形式: 另一种是repr(),将值转换为合法的python表达式. >>> print repr(" ...
- vim编辑器基本操作介绍
vim编辑器基本操作介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 可能很多小伙伴都听说过vi编辑器或是vim编辑器.它们是Unix和Linux世界最流行的编辑器之一,他们的特 ...
- Swift学习笔记1
1.Swift 的String类型是值类型. 如果您创建了一个新的字符串,那么当其进行常量.变量赋值操作,或在函数/方法中传递时,会进行值拷贝. 任何情况下,都会对已有字符串值创建新副本,并对该新副本 ...
- Dubbo学习笔记10:Dubbo服务消费方启动流程源码分析
同理我们看下服务消费端启动流程时序图: 在<Dubbo整体架构分析>一文中,我们提到服务消费方需要使用ReferenceConfig API来消费服务,具体是调用代码(1)get()方法来 ...
- bzoj千题计划225:bzoj2143: 飞飞侠
http://www.lydsy.com/JudgeOnline/problem.php?id=2143 分层图最短路 把能够弹跳的曼哈顿距离看做能量 dp[i][j][k]表示在(i,j)位置,还有 ...
- C#的Struct
- linux解压
tar –xvf file.tar //解压 tar包tar -xzvf file.tar.gz //解压tar.gztar -xjvf file.tar.bz2 //解压 tar.bz2tar –x ...
- 1601O_HOME
马kaiyu https://blog.csdn.net/debugbugbg 胡guoxin https://blog.csdn.net/qq_41995727 张yizhong https: ...
- Oracle PLSql配置
1.安装Oracle客户端或者服务端 2.配置环境变量 <1>.一般如果安装了Oracle客户端或者服务端的话,在环境变种的Path中有Oracle的安装路径(计算机-属性-高级系统设置- ...