zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 82 (Rated for Div. 2)

    QAQ

    A. Erasing Zeroes

    题意:

    给你一个01串,问最少删掉多少个0使得串中的所有1都相邻。

    思路:

    简单题,详细见代码。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+10;
    typedef long long LL;
    int num[maxn];
    double E[maxn];
    int main()
    {
        int T;
        cin >> T;
        while(T--)
        {
            string s;
            cin >> s;
            int len  = s.size();
            int i = 0,j = len-1;
            for( i = 0;i<len;++i)
            {
                if(s[i]=='1')
                    break;
            }
            for( j;j>=0;--j)
                if(s[j]=='1')
                break;
                //-=cout <<i << " " <<j << endl;
            int num = 0;
            for(int k = i;k<=j;++k)
            {
                if(s[k]=='0')
                    ++num;
            }
            cout << num<< endl;
        }
        return 0;
    }

    B. National Project

    题意:

    你有n个盒子,你需要往里面去放物品,规则是这样的,必须从左到右开始放物品,你一天可以放一个物品,物品分为ac两种,给你两个数gb,代表你放数的规律是先放g天的物品a,然后在放b天的物品c,循环往复,某个盒子一旦被放置上物品以后就不能够被更改了,但是你可以在选择在某一天不放物品,求最少的天数能使得放置完了以后n个盒子中物品a的数目占到一半以上。

    思路:

    数学题,具体细节见代码。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+10;
    typedef long long LL;
    int num[maxn];
    double E[maxn];
    int main()
    {
        int T;
        cin >> T;
        while(T--)
        {
           LL n,g,b;
           cin >> n >> g >>b;
           LL tmp = (n+1)/2;
           LL ans = 0;
           if(tmp%g!=0)
            ans = tmp/(g)*(g+b)+tmp%(g);
        else
            ans = tmp/g*(g+b)-b;
           ans = max(ans,n);
           cout << ans << endl;
        }
        return 0;
    }

    C. Perfect Keyboard

    题意:

    给你一个字符串s,要求你构造出一个a-z的全排列t,使得在s中相邻的两个字符在t中也相邻。可以输Yes和出t,不可以输出No

    思路:

    考虑能构造的情况实际上就是,对于所有出现的字符,与他相邻的字符种类数不能超过两个,就可以根据s串构造出一个答案链,链的开头以及结尾都是一个只有一个字母相邻,中间则是有两个字母与其相邻,例如s = abcab,此时每个字母都有两个字母与其相邻,无论怎样改变a,b,c的相对位置,都没办法构造出满足条件的t串。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+10;
    typedef long long LL;
    bool vis[30];
    set<int>st[30];
    int main()
    {
        int T;
        cin >> T;
        while(T--)
        {
            string s;
            cin >> s;
            for(int i = 0;i<=26;++i)
            {
                vis[i] = false;
                st[i].clear();
            }
            int len = s.size();
            if(len ==1)
            {
                printf("YES
    ");
                printf("%c",s[0]);
                for(int i = 0;i<26;++i)
                {
                    if(!vis[i]&&i!=s[0]-'a')
                        printf("%c",i+'a');
                }
                printf("
    ");
                continue;
            }
            bool flag = true;
            for(int i = 0;i<len;++i)
            {
                vis[s[i]-'a'] = true;
                if(i!=0)
                {
                    st[s[i]-'a'].insert(s[i-1]-'a');
                }
                if(i!=len-1)
                {
                    st[s[i]-'a'].insert(s[i+1]-'a');
                }
                if(st[s[i]-'a'].size()>2)
                {
                    //cout << i << endl;
                    flag = false;
                    break;
                }
            }
            if(!flag)
            {
                printf("NO
    ");
                continue;
            }
            int id = -1;
            for(int i =0;i<=25;++i)
            {
                if(st[i].size()==1)
                {
                    id = i;
                    break;
                }
            }
            if(id==-1)
            {
                printf("NO
    ");
                continue;
            }
            int k = 0;
            string ans = "";
            ans+=(id+'a');
            ++k;
            id = *st[id].begin();
            set<int>::iterator it;
            //cout << id << " " << ans << endl;
            while(st[id].size()!=1)
            {
                ans+=(id+'a');
                ++k;
                for(it = st[id].begin();it!=st[id].end();++it)
                {
                    if(*it!=(ans[k-2]-'a'))
                    {
    
                        id = *it;
                        break;
                    }
                }
               // cout << id << " " << ans << endl;
            }
            ans+=(id+'a');
            for(int i = 0;i<26;++i)
            {
                if(!vis[i])
                    ans+=(i+'a');
            }
            printf("YES
    ");
            cout << ans << "
    ";
        }
        return 0;
    }

    D. Fill The Bag

    题意:

    你有一个大小为n的包,你还有m个物品,对于第i个物品它的大小是aiai一定是2k次幂,k是整数,你可以把某个物品分成等大的两个部分,这会增加一次分割次数。问用这m个物品去填满这个背包所需要的最小分割次数是多少,如果不可能填满,则输出-1

    思路:

    首先,因为物品可以被分隔,只要这些物品的总和大于等于n,那么就一定能填满背包。反之,就输出-1

    因为每一个数都是2k次幂,所以考虑根据二进制来解决问题,将每一个数转化为他的二进制形式,我们可以得到两个数组a,ba[i] 表示n的二进制表示中第i位的的值,b[i]表示在m个物品中第i位为1的数有多少个。接下来从低位到高位去遍历,明显,a[i]等于1时代表这一位需要从b中同样在这一位上构造出一个1来,设当前a[i] = 1b数组中小于等于第i位的所有数的和为sum,当sum>=2^i时,为了分割数最小,所以选择用小于等于第i位的所有数来拼凑出第i位为1的情况,反之,则必须要从比第i位高的其他位借位来拼凑出第i1的情况。相对应的更新分割次数以及相关值即可,详细细节可以看代码。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    LL n,m;
    LL num1[70],num2[70];
    int main()
    {
        int t;
        cin >> t;
        while(t--)
        {
            cin >> n >> m;
            for(int i = 0;i<=60;++i)
            {
                num1[i] = num2[i]  =0;
            }
            LL x;
            LL sum = 0;
            for(int i = 0;i<m;++i)
            {
                cin >> x;
                sum+=x;
                for(LL j = 0;j<=60;++j)
                {
                    if(x&(1ll<<j))
                    {
                        ++num1[j];
                    }
                }
            }
            for(LL j =0;j<=60;++j)
            {
                if(n&(1ll<<j))
                {
                    num2[j] =1;
                }
            }
            if(sum<n)
            {
                cout << -1 << "
    ";
                continue;
            }
            sum=0;
            for(int i = 0;i<=60;++i)
            {
                if(num1[i]&&num2[i])
                {
                    num1[i] -=1;
                    num2[i] = 0;
                }
            }
            int ans = 0;
            for(LL i = 0;i<=60;++i)
            {
                sum+=((LL)num1[i]*(1ll<<i));
               // cout << sum << " " << ans << " " << i<< "
    ";
                if(num2[i])
                {
                    if(sum>=(1ll<<i))
                    {
                        sum-=(1ll<<i);
                        num2[i] = 0;
                    }
                    else
                    {
                        LL j = i+1;
                        for(j;!num1[j];++j);
                        num1[j]-=1;
                        for(LL k = j-1;k>=i;--k)
                        {
                            ++ans;
                            ++num1[k];
                        }
                        sum+=(1ll<<i);
                    }
                }
            }
            cout << ans << "
    ";
    
        }
        return 0;
    }
  • 相关阅读:
    Andorid中写文件后在电脑上看不到的解决办法
    【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性
    OpenCV入门学习笔记
    视频播放(iOS开发)
    音频播放(iOS开发)
    iPad开发(相对于iPhone开发时专有的API)
    静态库/内存分析/通讯录/换肤/硬件信息获取
    Alpha冲刺! Day1
    软工团队
    软工团队
  • 原文地址:https://www.cnblogs.com/baihualiaoluan/p/12450286.html
Copyright © 2011-2022 走看看