Codeforces Round #530 (Div. 2) Solution
A. Snowball
签。
#include <bits/stdc++.h>
using namespace std; int w, h, u[], d[]; int main()
{
while (scanf("%d%d", &w, &h) != EOF)
{
for (int i = ; i < ; ++i) scanf("%d%d", u + i, d + i);
for (int i = h; i >= ; --i)
{
w += i;
for (int j = ; j < ; ++j) if (i == d[j])
{
w -= u[j];
w = max(w, );
}
}
printf("%d\n", w);
}
return ;
}
B. Squares and Segments
签.
#include <bits/stdc++.h>
using namespace std; int n;
int main()
{
while (scanf("%d", &n) != EOF)
{
int limit = sqrt(n);
int res = 1e9;
for (int i = ; i <= limit; ++i)
res = min(res, i + n / i + (n % i ? : ));
printf("%d\n", res);
}
return ;
}
C. Postcard
Solved.
题意:
一个不定字符串,
如果有一位上有糖果,那么它前面那一个字符可以选择留下获得丢失
如果有一位上有雪花,那么它前面那一个字符可以选择留下、丢失或者重复x次,x自定
问能否由一种合法的选择,使得确定后的字符串的长度为n
思路:
先排除两种情况,
第一种是去掉所有可以去掉的字符后,长度都大于n
第二种是保留所有的不定字符,并且没有雪花,此时长度小于n
那么其他情况都是可以构造的
考虑两种情况
第一种 没有雪花,那么只需要删掉一些字符使得满足题意,不合法情况在之前已经排除
第二种 有雪花,保留一个雪花字符,删掉其他字符,用雪花字符的重复来填充长度
#include <bits/stdc++.h>
using namespace std; #define N 1010
char s[N];
int n, len; int main()
{
while (scanf("%s", s + ) != EOF)
{
scanf("%d", &n);
len = strlen(s + );
int snow = , candy = ;
for (int i = ; i <= len; ++i)
{
if (s[i] == '*') ++snow;
if (s[i] == '?') ++candy;
}
if (len - * (snow + candy) > n) puts("Impossible");
else if (len - candy < n && snow == ) puts("Impossible");
else
{
string res = "";
if (snow == )
{
int needdel = len - candy - n;
for (int i = ; i <= len; ++i)
{
if (s[i] == '?') continue;
if (i != len && s[i + ] == '?')
{
if (needdel) --needdel;
else res += s[i];
}
else res += s[i];
}
}
else
{
int flag = true;
int needadd = n - (len - * (candy + snow));
for (int i = ; i <= len; ++i)
{
if (i != len && s[i + ] == '?') continue;
if (i != len && s[i + ] == '*' && !flag) continue;
if (s[i] == '?' || s[i] == '*') continue;
if (i != len && s[i + ] == '*')
{
flag = false;
while (needadd--) res += s[i];
}
else res += s[i];
}
}
cout << res << endl;
}
}
return ;
}
D. Sum in the tree
Solved.
题意:
有一棵树,有点权,知道奇数层所有点的到根的前缀点权和,偶数层的不知道
求如何分配点权使得满足限制条件并且所有点权和最小
思路:
尽量将点权分配给深度低的,因为这样它产生的贡献肯定比分给深度大的要高
那么一个偶数层点u最多可以分配的点权就是
$Min(s[v] - s[fa[u]])\ v为它的儿子$
判-1也很好判,上面这个Min值如果是负的就不行,因为点权大于等于0
对于奇数层点的话 直接算它点权
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
int n, s[N];
vector <int> G[N];
bool flag; ll res; ll dist[N];
void DFS(int u, int fa)
{
if (s[u] == -)
{
if (G[u].size() == ) return;
ll Min = (ll)1e18;
for (auto v : G[u]) if (v != fa)
Min = min(Min, s[v] - dist[fa]);
if (Min < )
{
flag = false;
return;
}
res += Min;
dist[u] = dist[fa] + Min;
}
else
{
dist[u] = s[u];
res += dist[u] - dist[fa];
}
for (auto v : G[u]) if (v != fa)
{
DFS(v, u);
if (!flag) return;
}
} int main()
{
while (scanf("%d", &n) != EOF)
{
flag = true; res = ;
for (int i = ; i <= n; ++i) G[i].clear();
for (int i = , p; i <= n; ++i)
{
scanf("%d", &p);
G[i].push_back(p);
G[p].push_back(i);
}
for (int i = ; i <= n; ++i) scanf("%d", s + i);
DFS(, );
if (!flag) res = -;
printf("%lld\n", res);
}
return ;
}
E. Nice table
Upsolved.
题意:
构造一个$n * m的字符串矩阵,只包含'A', 'G', 'C', 'T'$
使得$任意2 \cdot 2 的子矩形都包含'A', 'G', 'C', 'T'$
并且要与给出的矩阵不同的字符个数最少
思路:
要求满足$任意2 \cdot 2 的子矩形都包含'A', 'G', 'C', 'T'$
的矩阵要满足每一行都是由两个字符交替组成
或者每一列都是由两个字符交替组成
枚举即可
#include <bits/stdc++.h>
using namespace std; #define N 150010
int n, m, p;
string s[N];
string t[][] =
{
{
"AG",
"AC",
"AT",
"GC",
"GT",
"CT",
},
{
"CT",
"GT",
"CG",
"AT",
"AC",
"AG",
}
};
string res[][N]; void work_row(string a, string b)
{
for (int i = ; i < n; ++i) res[p][i].clear();
string tmp[];
int cnt[];
for (int i = ; i < n; ++i)
{
tmp[] = tmp[] = "";
cnt[] = cnt[] = ;
for (int j = ; j < m; ++j)
for (int k = ; k < ; ++k)
tmp[k] += (i & ) ? a[j % ^ k] : b[j % ^ k];
for (int j = ; j < m; ++j)
for (int k = ; k < ; ++k)
cnt[k] += tmp[k][j] != s[i][j];
if (cnt[] < cnt[])
res[p][i] = tmp[];
else
res[p][i] = tmp[];
}
++p;
} void work_col(string a, string b)
{
for (int i = ; i < n; ++i) res[p][i].clear();
string tmp[];
int cnt[];
for (int j = ; j < m; ++j)
{
tmp[] = tmp[] = "";
cnt[] = cnt[] = ;
for (int i = ; i < n; ++i)
for (int k = ; k < ; ++k)
tmp[k] += (j & ) ? a[i % ^ k] : b[i % ^ k];
for (int i = ; i < n; ++i)
for (int k = ; k < ; ++k)
cnt[k] += tmp[k][i] != s[i][j];
if (cnt[] < cnt[])
for (int i = ; i < n; ++i)
res[p][i] += tmp[][i];
else
for (int i = ; i < n; ++i)
res[p][i] += tmp[][i];
}
++p;
} int com(int x)
{
int tmp = ;
for (int i = ; i < n; ++i)
for (int j = ; j < m; ++j)
tmp += res[x][i][j] != s[i][j];
return tmp;
} int main()
{
ios::sync_with_stdio(false);
cin.tie(); cout.tie();
while (cin >> n >> m)
{
p = ;
for (int i = ; i < n; ++i) cin >> s[i];
for (int i = ; i < ; ++i)
work_row(t[][i], t[][i]);
for (int i = ; i < ; ++i)
work_col(t[][i], t[][i]);
int Min = (int)1e9, pos = -;
for (int i = ; i < ; ++i)
{
//puts("bug");
//for (int j = 0; j < n; ++j) cout << res[i][j] << "\n";
int tmp = com(i);
//cout << tmp << "\n";
if (tmp < Min)
{
Min = tmp;
pos = i;
}
}
for (int i = ; i < n; ++i) cout << res[pos][i] << "\n";
}
return ;
}
F. Cookies
Upsolved.
题意:
刚开始有一个砝码在根节点,两个玩家,
先手玩家可以选择将它移向它的某个儿子,
后手玩家可以选择移除掉通向它某个儿子的边,当然也可以选择跳过这个操作
先手玩家可以选择在什么时候停下来,并且回到根节点,回去的过程可以吃饼干
每个结点有饼干数量,以及吃掉该节点上的一块饼干需要的时间
吃饼干需要时间,在边上走也需要时间,总时间T的情况下吃到的最多的饼干
求双方都在最优操作下,先手玩家吃到的饼干的最多的数量
思路:
先处理出每个结点回去的答案,再二分答案,十分显然
怎么处理答案,
对于点u, 首先吃饼干的时间是$T - 2 * dist(root, u)$
那么用权值BIT维护时间,以及饼干数量,二分查找在剩余时间的可以吃的最大饼干数量
注意处理尾部的部分
再二分答案,dp验证
考虑什么样的情况是合理的,我们假定某一个点是必胜态,那么这个点的深度如果<=1,
那么先手必胜,因为先手先移动
再考虑哪些点是必胜态,如果该点的处理出的饼干数量$ > limit$ 那么就是必胜态
又或者该点有2个儿子以上的点是必胜态,该点也是必胜态,因为后手玩家每次只能删去一条边
递归判断即可
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
#define M 1000010
int n; ll T;
int x[N], t[N], l[N];
vector <int> G[N]; namespace BIT
{
ll val[M], sum[M], a[M];
void init()
{
memset(val, , sizeof val);
memset(sum, , sizeof sum);
memset(a, , sizeof a);
}
void update(int x, ll v)
{
ll sumv = v * x;
a[x] += v;
for (; x < M; x += x & -x)
{
val[x] += v;
sum[x] += sumv;
}
}
ll query(ll T)
{
int l = , r = M - ;
ll res = ;
while (r - l >= )
{
int mid = (l + r) >> ;
int x = mid;
ll score = , sumt = ;
for (; x; x -= x & -x)
{
score += val[x];
sumt += sum[x];
}
if (sumt <= T)
{
score += min(a[mid + ], ((T - sumt) / (mid + )));
res = score;
l = mid + ;
}
else
r = mid - ;
}
return res;
}
} int fa[N], deep[N];
ll dist[N], score[N];
void DFS(int u)
{
for (auto v : G[u]) if (v != fa[u])
{
deep[v] = deep[u] + ;
dist[v] = dist[u] + l[v];
BIT::update(t[v], x[v]);
score[v] = BIT::query(T - 2ll * dist[v]);
DFS(v);
BIT::update(t[v], -x[v]);
}
} bool vis[N];
void dp(int u, ll x)
{
if (score[u] >= x)
{
vis[u] = ;
return;
}
int cnt = ;
for (auto v : G[u]) if (v != fa[u])
{
dp(v, x);
cnt += vis[v];
}
if (cnt >= ) vis[u] = ;
} bool check(ll x)
{
memset(vis, , sizeof vis);
dp(, x);
for (int i = ; i <= n; ++i) if (deep[i] <= && vis[i])
return ;
return ;
} void init()
{
for (int i = ; i <= n; ++i) G[i].clear();
BIT::init();
} int main()
{
while (scanf("%d%lld", &n, &T) != EOF)
{
init();
for (int i = ; i <= n; ++i) scanf("%d", x + i);
for (int i = ; i <= n; ++i) scanf("%d", t + i);
for (int i = ; i <= n; ++i)
{
scanf("%d%d", fa + i, l + i);
G[i].push_back(fa[i]);
G[fa[i]].push_back(i);
}
BIT::update(t[], x[]); score[] = BIT::query(T); dist[] = ; deep[] = ;
DFS();
ll l = , r = (ll)1e11 + , res = ;
while (r - l >= )
{
ll mid = (l + r) >> ;
if (check(mid))
{
res = mid;
l = mid + ;
}
else
r = mid - ;
}
printf("%lld\n", res);
}
return ;
}
Codeforces Round #530 (Div. 2) Solution的更多相关文章
- Codeforces Round #466 (Div. 2) Solution
从这里开始 题目列表 小结 Problem A Points on the line Problem B Our Tanya is Crying Out Loud Problem C Phone Nu ...
- 老年OIer的Python实践记—— Codeforces Round #555 (Div. 3) solution
对没错下面的代码全部是python 3(除了E的那个multiset) 题目链接:https://codeforces.com/contest/1157 A. Reachable Numbers 按位 ...
- Codeforces Round #545 (Div. 1) Solution
人生第一场Div. 1 结果因为想D想太久不晓得Floyd判环法.C不会拆点.E想了个奇奇怪怪的set+堆+一堆乱七八糟的标记的贼难写的做法滚粗了qwq靠手速上分qwqqq A. Skyscraper ...
- Codeforces Round #530 (Div. 2) F (树形dp+线段树)
F. Cookies 链接:http://codeforces.com/contest/1099/problem/F 题意: 给你一棵树,树上有n个节点,每个节点上有ai块饼干,在这个节点上的每块饼干 ...
- Codeforces Round #530 (Div. 2) A,B,C,D
A. Snowball 链接:http://codeforces.com/contest/1099/problem/A 思路:模拟 代码: #include<bits/stdc++.h> ...
- Codeforces Round 500 (Div 2) Solution
从这里开始 题目地址 瞎扯 Problem A Piles With Stones Problem B And Problem C Photo of The Sky Problem D Chemica ...
- Codeforces Round #530 (Div. 2):D. Sum in the tree (题解)
D. Sum in the tree 题目链接:https://codeforces.com/contest/1099/problem/D 题意: 给出一棵树,以及每个点的si,这里的si代表从i号结 ...
- Codeforces Round #530 (Div. 2) F 线段树 + 树形dp(自下往上)
https://codeforces.com/contest/1099/problem/F 题意 一颗n个节点的树上,每个点都有\(x[i]\)个饼干,然后在i节点上吃一个饼干的时间是\(t[i]\) ...
- Codeforces Round #607 (Div. 1) Solution
从这里开始 比赛目录 我又不太会 div 1 A? 我菜爆了... Problem A Cut and Paste 暴力模拟一下. Code #include <bits/stdc++.h> ...
随机推荐
- Python MySQLdb 模块
MySQLdb 是 Python2 连接 MySQL 的一个模块,常见用法如下: [root@localhost ~]$ yum install -y MySQL-python # 安装 MySQLd ...
- C语言中的文本流与二进制流的区别
近期看到了文本流和二进制流的区别,书上讲的比较含糊,理解不透彻,于是细细琢磨了下,把心得跟大家分享一下: 一.首先回答,什么是文件,流 一个文件通常就是磁盘上的一段命名的存储区.比如 stdio.h ...
- Win7下使用Putty代替超级终端通过COM串口连接开发板方法
1.如果电脑(笔记本)没有串口接口,则需要使用一个 USB-Serial 转换线,这里使用 prolific usb-serial USB--串口转换线,首先需要在win7上安装对应的 USB--串口 ...
- iOS - 布局重绘机制相关方法的研究
iOS View布局重绘机制相关方法 布局 - (void)layoutSubviews - (void)layoutIfNeeded- (void)setNeedsLayout —————————— ...
- Delphi使用ADO连接网络数据库,断网后重连问题
原始文章: https://blog.csdn.net/blog_jihq/article/details/11737699# 使用TADOConnection对象连接网络数据库(以MySQL为例), ...
- Angular基础---->AngularJS的使用(一)
AngularJS主要用于构建单页面的Web应用.它通过增加开发人员和常见Web应用开发任务之间的抽象级别,使构建交互式的现代Web应用变得更加简单.今天,我们就开始Angular环境的搭建和第一个实 ...
- 设计模式之单例模式(JAVA实现)
单例模式之自我介绍 我,单例模式(Singleton Pattern)是一个比较简单的模式,我的定义如下: Ensure a class has only one instance,and provi ...
- JS-【同页面多次调用】轮播特效封装-json传多个参数
看着传那么一长串的参数神烦,继续深化!——json传参: html: <div class="scrollBanner"> <ul class="ban ...
- [Bootstrap] install Bootstrap framework in window 7 by npm
Install with npm You can also install Bootstrap using npm: $ npm install bootstrap require('bootstra ...
- windowSoftInputMode
有个问题困扰我一晚上,每次进入Activity后,EditText自动获得焦点弹出软键盘,键盘遮挡listView,使得无法显示最后一条消息.我在edittext点击事件中也设定了,listView. ...