码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 1303 题解(更新中)

时间:2020-02-13 13:07:11      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:bre   %s   int   最大值   i+1   数据   开始   boa   keyboard   

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!\n")
#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\n",max(0,zerocnt-endzero-stzero));
    }
    return 0;
}

B. National Project

铺水泥,要求高质量水泥天数在 \(\left \lceil \frac{n}{2} \right \rceil\) 及以上,那其实我们可以假设要求 \(\left \lceil \frac{n}{2} \right \rceil\) 都是高质量水泥,然后和 \(n\) 取最大值即是答案。问题是要求 \(\left \lceil \frac{n}{2} \right \rceil\) 全是高质量水泥的天数怎么求?

我们可以将 \(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!\n")
#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\n",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!\n")
#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\n");
            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\n%s\n",rnt.c_str());
    }
    return 0;
}

codeforces 1303 题解(更新中)

标签:bre   %s   int   最大值   i+1   数据   开始   boa   keyboard   

原文地址:https://www.cnblogs.com/Asurudo/p/12302930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!