牛客周赛Round 85(全解)

比赛链接:https://ac.nowcoder.com/acm/contest/103948
继续AK。牛客周赛最近出题难度变低了,最近没出现特别能长知识的题了,反倒是语文方面(设坑)下了些功夫

A.小紫的均势博弈

思路:小博弈

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll                  long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
ll ksm(ll x, ll y)
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s
{
    ll l, r;
    friend bool operator<(const s& a, const s& b)
    {

        return a.l < b.l;
    }
};
string f[105];
int main()
{
    fio();
    ll t;
    t=1;
    //cin >> t;
    while (t--)
    {
       ll n;
       cin>>n;
       if(n&1)
       {
        cout<<"kou"<<endl;
       }
       else 
       {
        cout<<"yukari"<<endl;
       }
    }
}

B.小紫的劣势博弈

思路:小红想最小,那就拿最小的数,小紫想最大,那就减最小的数,排个序,然后奇加偶减即可

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll                  long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
ll ksm(ll x, ll y)
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s
{
    ll l, r;
    friend bool operator<(const s& a, const s& b)
    {

        return a.l < b.l;
    }
};
ll a[150000];
int main()
{
    fio();
    ll t;
    t=1;
    //cin >> t;
    while (t--)
    {
       ll n;
       cin>>n;
       //vector<llg>(n+5);
       for(ll i=1;i<=n;i++)
       {
        cin>>a[i];
       }
       sort(a+1,a+1+n);
       ll ans=0;
       for(ll i=1;i<=n;i++)
       {
        if(i&1)
        ans+=a[i];
        else ans-=a[i];
       }
       cout<<ans<<endl;
    }
}

C.小紫的01串操作

思路:通过观察法,可发现101010这种连续不同的个数w为6大于5无解,小于等于5有解

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll                  long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
ll ksm(ll x, ll y)
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s
{
    ll l, r;
    friend bool operator<(const s& a, const s& b)
    {

        return a.l < b.l;
    }
};
ll a[150000];
int main()
{
    fio();
    ll t;
    // t=1;
   cin >> t;
    while (t--)
    {
    string f;
    cin>>f;
    char g='#';
    ll cnt=0;
    for(ll i=0;i<f.size();i++)
    {
        if(g==f[i])continue;
        else 
        {
            g=f[i];
            cnt++;
        }
    }
    cout<<(cnt<=5?"Yes":"No")<<endl;
    }
}
//1010
//10101
//101010

D.小紫的优势博弈

思路:显然都可以想到去枚举删除的前缀(1~n),那么剩下的0,1个数我们就知道了,由于小紫只能删除后缀(也可以不删除),所以做个后缀map<pair<ll,ll>,ll>记录下后缀0,1对数,奇偶化即可。
那么我们枚举的时候先在map删除现在的0,1对数,然后问下的0,1对数是否存在可能即可(知道奇偶性即可),因为偶数减偶数等于偶数,奇数减奇数等于奇数,然后直接求概率即可,记得小数点多输出点(被坑两次,QwQ)

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll                  long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
ll ksm(ll x, ll y)
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s
{
    ll l, r;
    friend bool operator<(const s& a, const s& b)
    {

        return a.l < b.l;
    }
};
ll a[150000];
int main()
{
    fio();
    ll t;
     t=1;
   //cin >> t;
    while (t--)
    {
        ll n;
        cin>>n;
        string f;
        cin>>f;
        ll cn1=0;
        ll cn2=0;
        map<pair<ll,ll>,ll>k;
        for(ll i=f.size()-1;i>=0;i--)
        {
            if(f[i]=='0')cn1++;
            else cn2++;
            k[{cn1%2,cn2%2}]++;
        }
        k[{0,0}]++;
        double ans=0;
        k[{cn1%2,cn2%2}]--;
        for(ll i=0;i<f.size();i++)
        { 
            if(f[i]=='0')cn1--;
            else cn2--;
            k[{cn1%2,cn2%2}]--;
            if(k[{cn1%2,cn2%2}]>0)ans+=(double)1/n;
        }
        printf("%.7f\n",ans);
    }
}
//1010
//10101
//101010

E.小紫的线段染色

思路:首先判断有没有个点存在大于等于3个线段同时覆盖,这个点出现即无解,用优先队列即可得出.然后染色就在走一遍这个优先队列(这个要带原来下标),然后开个数组,表示现在的端是什么颜色即可,然后两个线段重合即取反,比如0为红,1为紫,所有颜色为1的点存到vector,然后输出即可。注意这里输出必须是正整数(如果要是vector没存染色点(没有线段存在覆盖情况),那就染色1即可)

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll                  long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
ll ksm(ll x, ll y)
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s
{
    ll l, r,id;
    friend bool operator<(const s& a, const s& b)
    {

        if(a.l!=b.l)
        return a.l < b.l;
        else return a.r<b.r;
    }
}p[250000];
ll a[150000];
int main()
{
    fio();
    ll t;
     t=1;
   //cin >> t;
    while (t--)
    {
        ll n;
        cin>>n;
        vector<ll>co(n+5,0);
        for(ll i=1;i<=n;i++)
        {
            cin>>p[i].l>>p[i].r;
            p[i].id=i;
        }
        sort(p+1,p+1+n);
        priority_queue<ll,vector<ll>,greater<ll>>f;
        ll pd=0;
        for(ll i=1;i<=n;i++)
        {
            f.push(p[i].r);
            while(!f.empty()&&f.top()<p[i].l)f.pop();
            if(f.size()>=3)pd=1;
        }
        if(pd)
        cout<<-1<<endl;
        else
        {
            priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>>x;
            vector<ll>ans;
            for(ll i=1;i<=n;i++)
            {
            while(!x.empty()&&x.top().first<p[i].l)x.pop();
            if(x.size()>0)
            {
                if(co[x.top().second]==0)co[p[i].id]=1,ans.push_back(p[i].id);
                else co[p[i].id]=0;
            }
            x.push({p[i].r,p[i].id});
            }
            if(ans.size()==0)ans.push_back(1);
            cout<<ans.size()<<endl;
            for(auto j:ans)
            {
                cout<<j<<" ";
            }
            cout<<endl;
        }
    }
}
//1010
//10101
//101010

F.小紫的树上染色

思路:二分+dfs,二分下最大红色连通块大小,然后得通过回溯进行切割(因为从叶子回来就可以不用考虑割了之后向下传得情况了)

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll                  long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
ll ksm(ll x, ll y)
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s
{
    ll l, r,id;
    friend bool operator<(const s& a, const s& b)
    {

        if(a.l!=b.l)
        return a.l < b.l;
        else return a.r<b.r;
    }
}p[250000];
ll a[150000];
int main()
{
    fio();
    ll t;
     t=1;
    while (t--)
    {
        ll n,k;
        cin>>n>>k;
        if(n==k)
        {
            cout<<0<<endl;
        }
        else 
        {
            vector<ll>g[n+5];
            for(ll i=1;i<n;i++)
            {
                ll l,r;
                cin>>l>>r;
                g[l].push_back(r);
                g[r].push_back(l);
            }
            ll cs=0;
            ll pd=0;
            function<ll(ll,ll,ll)>ck=[&](ll x,ll f,ll z)
            {
                ll cnt=1;
                for(auto j:g[x])
                {
                    if(j==f)continue;
                    ll xx=ck(j,x,z);
                    cnt+=xx;
                } 
                if(cnt>z)cnt=0,cs++;
                if(x==1)
                {
                    if(cs>k)return (ll)0;
                    else return (ll)1;
                }   
               
                return cnt;
            };
            ll l=1,r=n;
            while(l<r)
            {
                cs=0;
                ll mid=(l+r)>>1;
                if(ck(1,0,mid))
                {
                    r=mid;
                }
                else l=mid+1;
            }
            cout<<r<<endl;
        }
    }
}
//1010
//10101
//101010
posted @ 2025-03-16 21:01  长皆  阅读(211)  评论(0)    收藏  举报