ZOJ Monthly, June 2018 Solution
A - Peer Review
Water.
#include <bits/stdc++.h>
using namespace std; int t, n; int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = ; i <= n; ++i) printf("0%c", " \n"[i == n]);
}
return ;
}
B - Boring Game
Unsolved.
C - Enigma Machine
Unsolved.
D - Number Theory
Unsolved.
E - Chasing
Solved.
题意:两个人在一个二维平面上,刚开始两个人在第二象限或者第三象限,A跑到Y轴B就不能追了,B的速度是A的K倍,求B能否追到B
思路:k < 0 那么必然不行
k == 0 判断是不是在同一高度,如果是判断起始位置
k > 0 假设y轴上存在某个点 使得A B 能够在该点相遇,列方程求解
#include<bits/stdc++.h> using namespace std; double xa, xb, ya, yb, k; int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%lf %lf %lf %lf %lf", &xa, &ya, &xb, &yb, &k);
if(k < 1.0)
{
puts("N");
}
else if(k == 1.0)
{
if(ya != yb) puts("N");
else if(xb < xa) puts("N");
else puts("Y");
}
else
{
double a = k * k - 1.0;
double b = -2.0 * k * k * ya + 2.0 * yb;
double c = k * k * xa * xa - xb * xb + k * k * ya * ya - yb * yb;
double d = b * b - 4.0 * a * c;
if(d >= ) puts("N");
else puts("Y");
}
}
return ;
}
F - Carrot Gathering
Unsolved.
G - Virtual Singers
Upsolved.
题意:
H - How Many Palindromes
Unsolved.
题意:
有$n个A数和m个B数 m <= n,对每个B数都匹配一个A数,使得\sum_{i = 1}^{i = m} |B[i] - A[i]| 最小$
思路:
考虑费用流的思想,维护三个堆
将$A、B 数放在一起排序,然后从左往右枚举$
$如果当前数是A$
如果左边有未匹配的$B_1数,那么与之匹配即可,此操作不用考虑反悔操作$
$因为假如有另一个B_2,使得B_2 与 这个A匹配更优$
那么后面必然要有另一个$A_2 来匹配这个B_1 $
$贡献是 A_2 - B_1 + B_2 - A_1 这个式子显然小于 A_2 - B_2 + A_1 - B_1$
因为这四个数字存在大小关系
$A_2 - B_1 大于 A_2 - B_2 + A_1 - B_1$
如果左边没有未匹配的$B_1数,那么考虑B的反悔操作是否更优$
$更优的话就反悔并且将代价取反并算上A往右匹配的贡献放入堆Q_A中, 相当于反悔操作$
$如果当前数是B$
$如果左边有未匹配的A数,那么与之匹配,并且将代价取反并且算上B往右匹配的贡献放入堆Q_C中$
否则放入堆$Q_B$中表示还未匹配
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
int t, n, m; ll x;
struct node
{
ll v; int Type;
node () {}
node (ll v, int Type) : v(v), Type(Type) {}
bool operator < (const node &r) const { return v < r.v; }
}arr[N << ];
priority_queue <ll, vector <ll> , greater <ll> > A, B, C; int main()
{
scanf("%d", &t);
while (t--)
{
while (!A.empty()) A.pop();
while (!B.empty()) B.pop();
while (!C.empty()) C.pop();
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i)
{
scanf("%lld", &x);
arr[i] = node(x, );
}
for (int i = ; i <= m; ++i)
{
scanf("%lld", &x);
arr[n + i] = node(x, );
}
sort(arr + , arr + + n + m);
ll res = ;
for (int i = ; i <= n + m; ++i)
{
if (arr[i].Type == )
{
if (!A.empty())
{
x = A.top(); A.pop();
res += arr[i].v + x;
C.push(-x - * arr[i].v);
}
else
B.push(-arr[i].v);
}
else
{
if (!B.empty())
{
x = B.top(); B.pop();
res += arr[i].v + x;
}
else if (!C.empty())
{
x = C.top();
if (arr[i].v + x < )
{
C.pop();
res += arr[i].v + x;
A.push(-x - * arr[i].v);
}
else
A.push(-arr[i].v);
}
else
A.push(-arr[i].v);
}
}
printf("%lld\n", res);
}
return ;
}
I - District Division
Solved.
题意:给出一棵树,求能不能分成$\frac{n}{k}$ 个连通块,使得每块个数为k
思路:如果存在合法分法,那么必然存在某个子树大小为k,DFS下去,再回溯上来判断即可,遇到大小为k的子树就分块
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + ; int n, k; int val[maxn];
int fa[maxn];
int vis[maxn];
int cnt;
vector<int>root;
vector<int>G[maxn]; void Init()
{
cnt = ;
root.clear();
for(int i = ; i <= n; ++i)
{
val[i] = vis[i] = ;
fa[i] = i;
G[i].clear();
}
} void DFS(int u, int pre)
{
val[u] = ;
fa[u] = pre;
for(int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if(v == pre) continue;
DFS(v, u);
val[u] += val[v];
}
if(val[u] == k)
{
cnt++;
val[u] = ;
root.push_back(u);
}
} void DFS2(int u, int pre)
{
if(vis[u]) return ;
vis[u] = ;
printf("%d%c", u, " \n"[cnt == k]);
cnt++;
for(int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if(v == pre) continue;
DFS2(v, u);
}
} int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &n, &k);
Init();
for(int i = ; i < n; ++i)
{
int u, v;
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
DFS(, -);
if(cnt != n / k)
{
puts("NO");
continue;
}
puts("YES");
for(int i = , len = root.size(); i < len; ++i)
{
cnt = ;
DFS2(root[i], fa[root[i]]);
}
}
return ;
}
J - Good Permutation
Solved.
题意:每次能够交换相邻两个数,求最少交换次数使得满足题目给出的序列条件
思路:通过枚举每次在第一位的数,从而递推下一种状态,比如12345推出51234即加上5移到第一位的步数再减去5带来的贡献
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + ; int n;
int arr[maxn];
int pos[maxn];
int a[maxn]; int lowbit(int p)
{
return p & (-p);
} void update(int p)
{
while(p <= n)
{
a[p]++;
p += lowbit(p);
}
} int query(int p)
{
int res = ;
while(p)
{
res += a[p];
p -= lowbit(p);
}
return res;
} int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
ll ans = ;
for(int i = ; i <= n; ++i) a[i] = ;
for(int i = ; i <= n; ++i)
{
scanf("%d", arr + i);
pos[arr[i]] = i;
}
for(int i = n; i >= ; --i)
{
ans += query(arr[i] - );
update(arr[i]);
}
ll tmp = ans;
for(int i = ; i <= n; ++i)
{
tmp = tmp + n - pos[i] - (pos[i] - );
ans = min(ans, tmp);
}
printf("%lld\n", ans);
}
return ;
}
ZOJ Monthly, June 2018 Solution的更多相关文章
- ZOJ Monthly, March 2018 Solution
A - Easy Number Game 水. #include <bits/stdc++.h> using namespace std; #define ll long long #de ...
- ZOJ Monthly, January 2018 Solution
A - Candy Game 水. #include <bits/stdc++.h> using namespace std; #define N 1010 int t, n; int a ...
- ZOJ 4010 Neighboring Characters(ZOJ Monthly, March 2018 Problem G,字符串匹配)
题目链接 ZOJ Monthly, March 2018 Problem G 题意 给定一个字符串.现在求一个下标范围$[0, n - 1]$的$01$序列$f$.$f[x] = 1$表示存在一种 ...
- ZOJ 4009 And Another Data Structure Problem(ZOJ Monthly, March 2018 Problem F,发现循环节 + 线段树 + 永久标记)
题目链接 ZOJ Monthly, March 2018 Problem F 题意很明确 这个模数很奇妙,在$[0, mod)$的所有数满足任意一个数立方$48$次对$mod$取模之后会回到本身. ...
- ZOJ Monthly, March 2018 题解
[题目链接] A. ZOJ 4004 - Easy Number Game 首先肯定是选择值最小的 $2*m$ 进行操作,这些数在操作的时候每次取一个最大的和最小的相乘是最优的. #include & ...
- ZOJ Monthly, January 2018 训练部分解题报告
A是水题,此处略去题解 B - PreSuffix ZOJ - 3995 (fail树+LCA) 给定多个字符串,每次询问查询两个字符串的一个后缀,该后缀必须是所有字符串中某个字符串的前缀,问该后缀最 ...
- ZOJ Monthly, June 2014 月赛BCDEFGH题题解
比赛链接:点击打开链接 上来先搞了f.c,,然后发现状态不正确,一下午都是脑洞大开,, 无脑wa,无脑ce...一样的错犯2次.. 硬着头皮搞了几发,最后20分钟码了一下G,不知道为什么把1直接当成不 ...
- ZOJ Monthly, January 2018
A 易知最优的方法是一次只拿一颗,石头数谁多谁赢,一样多后手赢 #include <map> #include <set> #include <ctime> #in ...
- ZOJ Monthly, March 2018
A. Easy Number Game 贪心将第$i$小的和第$2m-i+1$小的配对即可. #include<cstdio> #include<algorithm> usin ...
随机推荐
- dos命令临时和永久设置环境变量方法
方法一:批处理中,修改环境变量,一次性有效(也就是在当前的脚本中有效) CMD中运行:set path==%path%;d:/mypath 用 set path可以查看,当前的环境变量 方 ...
- M0 M4之GPIO初始化
新唐所有的M0/M4芯片基本上所有的IO都可以发生中断,为了符合大家的习惯还是有所谓的外部中断EINT0和EINT1.有2跟GPIO脚可以配置为EINT0功能和EINT1功能,分别将发生EINT0中断 ...
- 《C++ Primer Plus》15.4 RTTI 学习笔记
运行时类型识别RTTI(Runtime Type Identification) C++有三个支持RTTI的元素.* 如果可能的话,dynamic_cast运算符将使用一个指向基类的指针来生成一个指向 ...
- c++11 数值类型和字符串的相互转换
string和数值类型转换 c++11提供了to_string方法,可以方便的将各种数值类型转换为 字符串类型: std::string to_string(int value); std::stri ...
- 【PHP】算法进阶,获取给定值的最优组合:虚拟币抵扣问题解决方案
商城里边.虚拟币抵扣问题解决方案 虚拟币抵扣规则,按照以下规则执行: 1.如果一个订单包含多款商品,且均支持虚拟币抵扣时: 优先按照最大化使用虚拟币进行全额抵扣原则进行抵扣,若抵扣后用户虚拟币账号 ...
- Android 判断是否是Rtl
第一种方法: private boolean isRtl() { return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) ...
- 使用openssl生成RSA公钥和私钥对
在ubuntu上要使用openssl的话需要先进行安装,命令如下: sudo apt-get install openssl 安装完成就可以使用openssl了. 首先需要进入openssl的交互界面 ...
- c# 给button添加不规则的图片以及用pictureBox替代button响应点击事件
1.Flat button 用这个方法,前提是要把button的type设置为Flat button1.TabStop = false;button1.FlatAppearance.BorderSiz ...
- 聊一聊goroutine stack
通过阅读这篇文章对内存的处理以及栈的扩容有了新的认识,我们在生产环境中也遇到了内存使用量超大的情况,现在怀疑也可能是由于栈扩容导致的 很好的一片文章: 推送在外卖订餐中扮演着重要的角色,为商家实时接单 ...
- python的tqdm模块
Tqdm 是一个快速,可扩展的Python进度条,可以在 Python 长循环中添加一个进度提示信息,用户只需要封装任意的迭代器 tqdm(iterator). 根据要求安装依赖即可. 可以很方便的在 ...