https://codeforces.com/contest/1287/

A - Angry Students

题意:求A后面的P最长连续有几个?

题解:?

int n;
char s[200005]; void test_case() {
scanf("%d%s", &n, s + 1);
int cnt = 0, ans = 0;
int b = 1;
while(b <= n && s[b] == 'P')
++b;
for(int i = b; i <= n; ++i) {
if(s[i] == 'P')
++cnt;
else {
ans = max(ans, cnt);
cnt = 0;
}
}
ans = max(ans, cnt);
printf("%d\n", ans);
}

一种不需要判断结尾的思路是,一边统计cnt,一边尝试更新ans。

B - Hyperset

题意:每个属性只有3种值。定义三张牌是一个SET,当他们每个属性要么全等要么两两不同。

题解:枚举两张牌,可以确定第三张牌。

注:原来没有重复的牌的啊,这个constraint完全没必要啊,把这题变成一个送分题了。

struct TrieNode {
int data;
int nxt[3]; void Init() {
data = 0;
memset(nxt, 0, sizeof(nxt));
}
}; struct Trie {
static const int MAXN = 45000;
TrieNode tn[MAXN + 5];
int root, top; int NewNode() {
tn[++top].Init();
return top;
} void Init() {
top = 0;
root = NewNode();
} void Insert(int *a, int len, int data) {
int cur = root;
for(int i = 1; i <= len; ++i) {
int &nxt = tn[cur].nxt[a[i]];
if(!nxt)
nxt = NewNode();
cur = nxt;
}
tn[cur].data += data;
} int Query(int *a, int len) {
int cur = root;
for(int i = 1; i <= len; ++i) {
int &nxt = tn[cur].nxt[a[i]];
if(!nxt)
return 0;
cur = nxt;
}
return tn[cur].data;
}
} trie; int n, k;
char s[35];
int st[128], t[1505][35], r[35]; void test_case() {
st['S'] = 0;
st['E'] = 1;
st['T'] = 2;
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; ++i) {
scanf("%s", s + 1);
for(int j = 1; j <= k; ++j)
t[i][j] = st[s[j]];
trie.Insert(t[i], k, 1);
}
ll sum = 0;
for(int i1 = 1; i1 <= n; ++i1) {
for(int i2 = i1 + 1; i2 <= n; ++i2) {
int ty = 1;
for(int j = 1; j <= k; ++j) {
r[j] = (3 - (t[i1][j] + t[i2][j]) % 3) % 3;
if(r[j] != t[i1][j])
ty = 0;
}
if(ty == 0)
sum += trie.Query(r, k);
else
sum += trie.Query(r, k) - 2;
}
}
printf("%lld\n", sum / 3);
}
map<ll, int> M;

int n, k;
char s[35];
int st[128], t[1505][35];
ll val[1505]; void test_case() {
st['S'] = 0;
st['E'] = 1;
st['T'] = 2;
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; ++i) {
scanf("%s", s + 1);
ll r = 0;
for(int j = 1; j <= k; ++j) {
t[i][j] = st[s[j]];
r = 3 * r + t[i][j];
}
M[r]++;
val[i] = r;
}
ll sum = 0;
for(int i1 = 1; i1 <= n; ++i1) {
for(int i2 = i1 + 1; i2 <= n; ++i2) {
ll r = 0;
for(int j = 1; j <= k; ++j) {
int tmp = (3 - (t[i1][j] + t[i2][j]) % 3) % 3;
r = 3ll * r + tmp;
}
auto it = M.find(r);
if(it != M.end()) {
if(r != val[i1])
sum += it->second;
else
sum += (it->second) - 2;
}
}
}
printf("%lld\n", sum / 3);
}
unordered_map<ll, int> M;

int n, k;
char s[35];
int st[128], t[1505][35];
ll val[1505]; void test_case() {
M.reserve(3000);
st['S'] = 0;
st['E'] = 1;
st['T'] = 2;
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; ++i) {
scanf("%s", s + 1);
ll r = 0;
for(int j = 1; j <= k; ++j) {
t[i][j] = st[s[j]];
r = 3 * r + t[i][j];
}
M[r]++;
val[i] = r;
}
ll sum = 0;
for(int i1 = 1; i1 <= n; ++i1) {
for(int i2 = i1 + 1; i2 <= n; ++i2) {
ll r = 0;
for(int j = 1; j <= k; ++j) {
int tmp = (3 - (t[i1][j] + t[i2][j]) % 3) % 3;
r = 3ll * r + tmp;
}
auto it = M.find(r);
if(it != M.end()) {
if(r != val[i1])
sum += it->second;
else
sum += (it->second) - 2;
}
}
}
printf("%lld\n", sum / 3);
}

Trie最快,但是一开始开太紧空间WA了一发。事实上真的没必要省空间,有多大开多大。

C - Garland

这个怎么贪心的啊?得看看别人怎么搞。

题意:给一列数字,是一个自然数的排列,假如是0表示待填。填上这个序列使得复杂度最小。每个相邻的奇偶对贡献1复杂度。

题解:dp,由于奇数之间是等价的,偶数之间也是等价的,每种填法对后面的影响也是只有最后一位数字。设dp[i][j][0/1]为前i个位置填了j个奇数,并且最后一位的奇偶性为0/1的最小复杂度。

int a[105];
int dp[105][105][2]; void test_case() {
int n;
scanf("%d", &n);
int cnt1 = (n + 1) / 2;
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
if(a[i]) {
if(a[i] & 1)
--cnt1;
}
}
memset(dp, INF, sizeof(dp));
dp[0][0][0] = 0;
dp[0][0][1] = 0;
for(int i = 1; i <= n; ++i) {
if(a[i]) {
int t = a[i] & 1;
for(int j = 0; j <= cnt1; ++j) {
dp[i][j][t] = dp[i - 1][j][t];
dp[i][j][t] = min(dp[i][j][t], dp[i - 1][j][1 - t] + 1);
}
} else {
for(int j = 1; j <= cnt1; ++j) {
dp[i][j][1] = dp[i - 1][j - 1][1];
dp[i][j][1] = min(dp[i][j][1], dp[i - 1][j - 1][0] + 1);
}
for(int j = 0; j <= cnt1; ++j) {
dp[i][j][0] = dp[i - 1][j][1] + 1;
dp[i][j][0] = min(dp[i][j][0], dp[i - 1][j][0]);
}
}
/*for(int j = 0; j <= cnt1; ++j) {
for(int t = 0; t <= 1; ++t)
printf("dp[%d][%d][%d]=%d\n", i, j, t, dp[i][j][t]);
}
puts("");*/
}
printf("%d\n", min(dp[n][cnt1][0], dp[n][cnt1][1]));
}
int a[105];
int dp[105][105][2]; void test_case() {
int n, c;
scanf("%d", &n);
c = (n + 1) / 2;
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]); memset(dp, INF, sizeof(dp));
dp[0][0][0] = 0;
dp[0][0][1] = 0;
for(int i = 1; i <= n; ++i) {
if(a[i]) {
int t = a[i] & 1;
for(int j = 0; j <= c; ++j) {
dp[i][j + t][t] = dp[i - 1][j][t];
dp[i][j + t][t] = min(dp[i][j + t][t], dp[i - 1][j][1 - t] + 1);
}
} else {
for(int j = 1; j <= c; ++j) {
dp[i][j][1] = dp[i - 1][j - 1][1];
dp[i][j][1] = min(dp[i][j][1], dp[i - 1][j - 1][0] + 1);
}
for(int j = 0; j <= c; ++j) {
dp[i][j][0] = dp[i - 1][j][1] + 1;
dp[i][j][0] = min(dp[i][j][0], dp[i - 1][j][0]);
}
}
/*for(int j = 0; j <= cnt1; ++j) {
for(int t = 0; t <= 1; ++t)
printf("dp[%d][%d][%d]=%d\n", i, j, t, dp[i][j][t]);
}
puts("");*/
}
printf("%d\n", min(dp[n][c][0], dp[n][c][1]));
}

贪心的解法复杂度低一个层次。

D - Numbers on Tree

题意:给一棵n<=2000的有根树,规定每个数的子树中有多少个节点的val比根节点的严格小。给这棵树填上任意一种合法的val(每个值都在[1,10^9]且满足上一句话)或报告不存在。

题解:树的这类问题可能都是先往递归的方向考虑,假如是叶子,不用多说之间返回1,否则是中间节点。假如中间节点只有一棵子树,而且子树中的值是相异的,那么随便插进去然后把后面的数往后面挤,得到的也还是值全部相异的树。否则至少有两棵子树,假如他们的值也都是相异的也可以仿照上面解决,可惜搞不得,有可能不存在一个位置刚好满足要求。

  1. 这时候很显然的子树之间是没有关系的,可以给一棵子树的值整体提高一个水平,使得得到的值也是相异的,最简单的是加上上一棵子树的最大值(而不一定是size,假如没有进行算不并列的排名的话)。

  2. 事实上并不一定需要同一棵子树占据同一段连续的位置,直接全部混在一起算不并列的排名也可以。

int n, root;

int c[2005];

vector<int> G[2005];
vector<pii> vec[2005]; void dfs(int u) {
for(auto &v : G[u]) {
dfs(v);
for(auto &j : vec[v])
vec[u].push_back(j);
}
if(c[u] > vec[u].size()) {
puts("NO");
exit(0);
}
sort(vec[u].begin(), vec[u].end());
for(int i = 0; i < vec[u].size(); ++i)
vec[u][i].first = i + 1;
vec[u].insert(vec[u].begin() + c[u], {c[u] + 1, u});
for(int i = c[u] + 1; i < vec[u].size(); ++i)
++vec[u][i].first;
} void test_case() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
int p;
scanf("%d%d", &p, &c[i]);
if(p)
G[p].push_back(i);
else
root = i;
}
dfs(root);
for(auto &j : vec[root])
swap(j.first, j.second);
sort(vec[root].begin(), vec[root].end());
puts("YES");
for(auto &j : vec[root])
printf("%d ", j.second);
puts("");
}

注意vector中insert是一个迭代器,而且确实可以在 for auto 中进行交换(应该在遍历中不会改变其他元素的操作都可以吧?)

Codeforces Round #612 (Div. 2)的更多相关文章

  1. Codeforces Round #612 (Div. 2) 前四题题解

    这场比赛的出题人挺有意思,全部magic成了青色. 还有题目中的图片特别有趣. 晚上没打,开virtual contest打的,就会前三道,我太菜了. 最后看着题解补了第四道. 比赛传送门 A. An ...

  2. Codeforces Round #612 (Div. 2)C. Garland

    第四次写题解,请多指教! http://codeforces.com/contest/1287/problem/C题目链接 题目大意是有一个数字串挂有1-n n个数字,现在上面缺失了一些数字,让你找出 ...

  3. Codeforces Round #612 (Div. 2) (A-D)

    直 接看所有A后面连续P的个数最大值 #include<cstring> #include<cstdio> #include<set> #include<io ...

  4. 【codeforces】Codeforces Round #612 (Div. 2) C. Garland——DP

    题目链接 贪心模拟了半天,最后放弃了 题意 给你一串从1−n1-n1−n的序列,其中部分未知(表示为0),补全序列使得相邻数值奇偶性相反的数量最少 相邻数值的奇偶性相反:两个相邻的两个数值,其中一个为 ...

  5. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  6. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  7. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  8. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  9. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

随机推荐

  1. swiper仿tab栏切换

    转载  https://developers.weixin.qq.com/community/develop/article/doc/000040a5dc4518005d2842fdf51c13 小程 ...

  2. Bert系列(三)——源码解读之Pre-train

    https://www.jianshu.com/p/22e462f01d8c pre-train是迁移学习的基础,虽然Google已经发布了各种预训练好的模型,而且因为资源消耗巨大,自己再预训练也不现 ...

  3. kuangbin专题-连通图A - Network of Schools

    这道题的意思是就是 问题 1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件. 2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校 ...

  4. hdu 2126 Buy the souvenirs(记录总方案数的01背包)

    Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  5. Python--day38--JoinableQueue解决生产者消费者模型

    ############################# # 在消费者这一端: #每次获取一个数据 #处理一个数据 #发送一个记号:标志一个数据被处理成功 #在生产者这一端: #每一次生成一个数据 ...

  6. 插播一条 WMI修复教程

    一般情况下,WMI都会好好的工作,但偶尔也会出现小问题. 这些小问题会影响到正在使用WMI的程序,比如设置的有线和无线网络依然还是依赖WMI的.如果WMI自己都没办法工作,有些数据就获取不到了. 先看 ...

  7. es6 let和const的用法

    ]()) {; } //console.log(MAX);//MAX is not defined" /*也有暂时性死区,声明的位置需要在使用前面,否则报错: * 不能重复声明变量 * */ ...

  8. LR性能测试自动化集成JENKINS

    LR11不支持JENKINS集成,解决方案可以使用BAT代替执行,JENKINS定时调用BAT执行性能测试用例.   1. 先随便录制l一个LR脚本,保存为 D:\TEST\test01 2. 打开 ...

  9. H3C查看CF卡内的文件

    查看CF卡内的文件 <H3C>dir             //查看文件及目录文件 Directory of cf:/ -------------查看的是CF卡的内容      0    ...

  10. dotnet 新项目格式与对应框架预定义的宏

    在 sdk style 的项目格式支持使用多框架开发,此时需要在代码里面通过宏判断,在编译的时候执行不同的代码.本文告诉大家在框架里面对应的预定义的条件编译符有哪些 在让一个 csproj 项目指定多 ...