codeforces 1303 题解(更新中)
Posted asurudo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces 1303 题解(更新中)相关的知识,希望对你有一定的参考价值。
codeforces 1303 题解
A. Erasing Zeroes
想让字符串中的 (1) 连续,而我们能做的只有删 (0) ,则需要删去除开头以及结尾外的 所有 (0) 块。所以从头扫一遍统计开头 (0) 块,从尾扫一遍统计结尾 (0) 块,再用 (0) 的数量减去这两部分即可,可能为负所以跟 (0) 取最大值。
时间复杂度 (O(n))
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define _for(i,a,b) for(int i = (a);i < b;i ++)
#define _rep(i,a,b) for(int i = (a);i > b;i --)
#define INF 0x3f3f3f3f
#define ZHUO 11100000007
#define MOD 1000000007
#define MIKUNUM 39
#define pb push_back
#define debug() printf("Miku Check OK!
")
#define maxn 239
#define X first
#define Y second
int main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while(t--)
{
string s;
cin >> s;
int stzero = 0, endzero = 0;
int zerocnt = 0;
_for(i,0,s.size())
if(s[i]=='0')
zerocnt ++;
_for(i,0,s.size())
if(s[i]=='1')
break;
else
stzero ++;
_rep(i,s.size()-1,-1)
if(s[i]=='1')
break;
else
endzero ++;
printf("%d
",max(0,zerocnt-endzero-stzero));
}
return 0;
}
B. National Project
铺水泥,要求高质量水泥天数在 (left lceil frac{n}{2} ight ceil) 及以上,那其实我们可以假设要求 (left lceil frac{n}{2} ight ceil) 都是高质量水泥,然后和 (n) 取最大值即是答案。问题是要求 (left lceil frac{n}{2} ight ceil) 全是高质量水泥的天数怎么求?
我们可以将 (g+b) 这个值打包成一个 组 ,因为他们是连续的。如果要求全是高质量水泥,答案至少应该包含最大可能的 组 值,然后再来一些 (g) 来凑。说的有点抽象,具体一点就是比如现在要求 (20)天 高质量水泥,(g==6,b==3) ,则 组 就是 (9) ,你至少需要 (3) 组,再来 (20-3×6=2) 个零散的 (g) 来凑就能凑够 (20) 天高质量水泥,也就是 (3×9+2=29) 天。
特殊考虑 (n|g) 的情况即可。
PS:样例中一百万天坏天气震撼我心。
时间复杂度 (O(1))。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define _for(i,a,b) for(int i = (a);i < b;i ++)
#define _rep(i,a,b) for(int i = (a);i > b;i --)
#define INF 0x3f3f3f3f
#define ZHUO 11100000007
#define MOD 1000000007
#define MIKUNUM 39
#define pb push_back
#define debug() printf("Miku Check OK!
")
#define maxn 239
#define X first
#define Y second
ll n, g, b, rnt;
int main()
{
ios::sync_with_stdio(false);
int T;
cin >> T;
while(T--)
{
cin >> n >> g >> b;
ll tmpn = n/2 + (n&0x1);
ll curhaveg = tmpn/g;
rnt = curhaveg * (g+b);
if(curhaveg*g == tmpn)
{
rnt -= g+b;
curhaveg -= 1;
}
rnt += tmpn-curhaveg*g;
printf("%lld
",max(n,rnt));
}
return 0;
}
C. Perfect Keyboard
我是负责图论和数据结构的所以咳咳...脑回路清奇,我们将每个字母看成一个节点,他们相邻就连边呗,啥情况输出 (NO) ?首先我们排除一下重边,然后就是如果有环肯定不行,自行证明一下吧,还有一个就是一个点的度大于等于 (3) 不行,这个也自己想一下为什么。
我用的是并查集判环,度直接开数组 (in) 判断。最后图构建好以后找一个度为 (1) 的点 (dfs) 一下,没加到答案里的字母最后加进去就行了。为什么找一个度为 (1) 的点开始 (dfs) 一遍就好?因为这个无向图一定是一棵树,而且只能从儿子开始遍历,还是自己想一下为什么。
杀鸡用了牛刀...勿喷
时间复杂度主要用在判重边了,所以整体时间复杂度 为 (O(nlogn+nα(n))=O(nlogn)) 。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define _for(i,a,b) for(int i = (a);i < b;i ++)
#define _rep(i,a,b) for(int i = (a);i > b;i --)
#define INF 0x3f3f3f3f
#define ZHUO 11100000007
#define MOD 1000000007
#define MIKUNUM 39
#define pb push_back
#define debug() printf("Miku Check OK!
")
#define X first
#define Y second
#define maxn 39
#define maxe 2003
struct Djs
{
int par[maxn];
int high[maxn];
void renew()
{
_for(i,1,maxn)
{
par[i] = i;
high[i] = 0;
}
}
int find(int x)
{
return par[x] == x ? x : par[x] = find(par[x]);
}
void unite(int x,int y)
{
x = find(x);
y = find(y);
if(x==y) return ;
if(high[x]<high[y])
par[x] = y;
else
{
par[y] = x;
if(high[x]==high[y])
high[x] ++;
}
}
bool same(int x,int y)
{
return find(x) == find(y);
}
}djs;
struct G
{
int n,m;
int Next[maxe];
int head[maxn];
int ver[maxe];
int tot;
void add(int x,int y)
{
ver[++tot] = y,Next[tot] = head[x],head[x] = tot;
}
void renew()
{
tot = 0;
n = 26;
memset(head,0,sizeof(head));
}
} g;
int to(char c)
{
return c-'a'+1;
}
int vis[27];
int in[27];
string rnt;
void dfs(int x)
{
rnt += x+'a'-1;
vis[x] = 1;
for(int i = g.head[x]; i; i = g.Next[i])
{
int y = g.ver[i];
if(vis[y])
continue;
dfs(y);
}
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while(t--)
{
string s;
cin >> s;
memset(vis,0,sizeof(vis));
memset(in,0,sizeof(in));
rnt.clear();
g.renew();
djs.renew();
set<pair<int,int>> st;
int flag = 0;
_for(i,0,s.size()-1)
{
if(st.count( {to(s[i]), to(s[i+1])} )
|| st.count( {to(s[i+1]), to(s[i])} ) )
continue;
if(djs.same( to(s[i]), to(s[i+1]) ) )
{
flag = 1;
break;
}
g.add(to(s[i]), to(s[i+1])),g.add(to(s[i+1]), to(s[i]));
st.insert({to(s[i]), to(s[i+1])});
djs.unite(to(s[i]), to(s[i+1]));
in[to(s[i])] ++,in[to(s[i+1])] ++;
if(in[to(s[i])] >= 3
|| in[to(s[i+1])] >= 3)
{
flag = 1;
break;
}
}
if(flag)
{
printf("NO
");
continue;
}
int sta;
_for(i,1,27)
if(in[i]==1)
sta = i;
if(s.size()!=1)
dfs(sta);
_for(i,1,27)
if(!vis[i])
rnt += i+'a'-1;
printf("YES
%s
",rnt.c_str());
}
return 0;
}
以上是关于codeforces 1303 题解(更新中)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #643 (Div. 2) 题解 (ABCD)(佛系更新中)
Codeforces Round #535 (Div. 3) 题解