首页 > 其他分享 >2023牛客暑期多校训练营8

2023牛客暑期多校训练营8

时间:2023-08-16 12:56:02浏览次数:44  
标签:back cur int void cin 多校 牛客 pos 2023

A.Alive Fossils

纯模拟没啥好说的

map<string,int>mp;
void solve()
{
    int n;cin>>n;
    for(int i=1;i<=n;i++)
    {
        int t;cin>>t;
        while(t--)
        {
            string s;cin>>s;
            mp[s]++;
        }
    }
    int res=0;
    set<string>st;
    for(auto it:mp)
    {
        if(it.second==n)
        {
            res++;
            st.insert(it.first);
        }
    }
    cout<<res<<"\n";
    for(auto it:st)
    {
        cout<<it<<"\n";
    }
}

H.Insert 1, Insert 2, Insert 3, ...

题意:给定长度为\(n\)的序列,问有多少个连续子区间满足这个子区间可以通过若干次依次按顺序插入\(1,2,3,...,k\)的子序列构成

Solution

对于一个右端点,它的合法左端点肯定是1,必须是1开头

我们可以用栈来找到对于\(x\)的最近的\(x-1\)的位置,则其中的1一定不合法

所以如果遇到整个都不合法的区间,则清空所有的1

void solve()
{
    int n;
    cin >> n;
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        if (x == 1)
        {
            s.push_back(i);
            e[x].push_back(i);
            ans += s.size();
        }
        else if (e[x - 1].empty())
        {
            s.clear();
        }
        else
        {
            int pos = e[x - 1].back();
            e[x - 1].pop_back();
            e[x].push_back(i);
            while (s.size() && s.back() > pos)
                s.pop_back();
            ans += s.size();
        }
    }
    cout << ans << "\n";
}

I.Make It Square

题意:有一个串\(n\),由两个回文串\(s,t\)和两个相同的未知串\(p,q\)组成,其中\(n,p,q\)是\(AA\)型的串,求满足条件的\(p,q\)对于其长度分别为\(1,2,...,k\)的个数

Solution

首先\(p+q\)一定是偶数,不是偶数则\(s\)也不能是偶数

\(|p|=|q|\)时,判断\(p,q\)是否完全一致,如果一致,则答案为\(26^i\)

令\(|p|=n,|q|=m\)

\(|p|>|q|\)时,分情况讨论

当\(i\leq(n-m)/2\)时,则有

发现,此时,\(p,q\)已经固定了,如果\(s,t\)在图中位置匹配,并且\(s\)有长度为\((n-m)/2-i\)的前后缀相同,答案为1,反之为0

当\(i>(n-m)/2\)时,则有

此时有\(i-(n-m)/2\)的是未确定的,如果s,t匹配的话,则答案为\(26^{i-\frac{n-m}{2}}\)(题解的图有点问题)

对于\(|p|<|q|\)的情况同理


void getkmp(string b, int kmp[])
{
    int j = 0;
    int lenb = b.length();
    b = "#" + b;
    for (int i = 2; i <= lenb; i++)
    {
        while (j && b[i] != b[j + 1])
            j = kmp[j];
        if (b[j + 1] == b[i])
            j++;
        kmp[i] = j;
    }
}

set<int> getBorder(string p, int nx[])
{
    set<int> s;
    int cur = nx[p.length()];
    while (cur)
    {
        s.insert(cur);
        cur = nx[cur];
    }
    s.insert(0);
    return s;
}

void solve()
{
    int m;
    cin >> m;
    string p, q;
    cin >> p >> q;
    getkmp(p, kmp1);
    getkmp(q, kmp2);
    set<int> b1, b2;
    b1 = getBorder(p, kmp1);
    b2 = getBorder(q, kmp2);
    // cout << kmp1[p.length()] << " " << kmp2[q.length()] << "\n";
    int x = p.length(), y = q.length();
    if (x == y)
    {
        int flag = 1;
        for (int i = 0; i < x; i++)
        {
            if (p[i] != q[i])
            {
                flag = 0;
                break;
            }
        }
        if (flag)
        {
            int res = 1;
            for (int i = 1; i <= m; i++)
            {
                res = (res * 26) % mod;
                cout << res << " ";
            }
        }
        else
        {
            for (int i = 1; i <= m; i++)
            {
                cout << "0 ";
            }
        }
    }
    else if ((x + y) & 1)
    {
        for (int i = 1; i <= m; i++)
        {
            cout << "0 ";
        }
    }
    else if (x > y)
    {
        int pos = (x - y) / 2;
        int flag = 1;
        for (int i = 0; i < y; i++)
        {
            if (p[pos] != q[i])
            {
                flag = 0;
                break;
            }
            pos++;
        }
        int res = 1;
        for (int i = 1; i <= m; i++)
        {
            if (!flag)
            {
                cout << "0 ";
                continue;
            }
            if (i <= (x - y) / 2)
            {
                if (b1.count((x - y) / 2 - i))
                {
                    cout << "1 ";
                }
                else
                {
                    cout << "0 ";
                }
            }
            else
            {
                res = (res * 26) % mod;
                cout << res << " ";
            }
        }
    }
    else if (x < y)
    {
        int pos = (y - x) / 2;
        int flag = 1;
        for (int i = 0; i < x; i++)
        {
            if (p[i] != q[pos])
            {
                flag = 0;
                break;
            }
            pos++;
        }
        int res = 1;
        for (int i = 1; i <= m; i++)
        {
            if (!flag)
            {
                cout << "0 ";
                continue;
            }
            if (i <= (y - x) / 2)
            {
                if (b2.count((y - x) / 2 - i))
                {
                    cout << "1 ";
                }
                else
                {
                    cout << "0 ";
                }
            }
            else
            {
                res = (res * 26) % mod;
                cout << res << " ";
            }
        }
    }
}

J.Permutation and Primes

题意:构造一个排列,使得相邻的数的和或者差是大于2的素数

Solution

看到别人有8循环的,我写个10循环的构造

令初始值为\(x\),则可以构造出\(\textcolor{red}{x,x+7,x+4,x+1,x+8,x+5,x+2,x+9,x+6,x+3},x+10\),红色的部分即为一个循环,我们可以打表找到长度从1到9的,这样就可以涵盖到全部的情况

int n;
int a[N];
int mov[10] = {7, -3, -3, 7, -3, -3, 7, -3, -3, 7};
void solve()
{
    cin >> n;
    if (n % 10 <= 4)
    {
        for (int i = 1; i <= n % 10; i++)
            a[i] = i;
    }
    else if (n % 10 == 5)
    {
        a[1] = 1, a[2] = 4, a[3] = 3, a[4] = 2, a[5] = 5;
    }
    else if (n % 10 == 6)
    {
        a[1] = 1, a[2] = 4, a[3] = 3, a[4] = 2, a[5] = 5, a[6] = 6;
    }
    else if (n % 10 == 7)
    {
        a[1] = 1, a[2] = 2, a[3] = 5, a[4] = 6, a[5] = 3, a[6] = 4, a[7] = 7;
    }
    else if (n % 10 == 8)
    {
        a[1] = 1, a[2] = 2, a[3] = 3, a[4] = 4, a[5] = 7, a[6] = 6, a[7] = 5, a[8] = 8;
    }
    else if (n % 10 == 9)
    {
        a[1] = 1, a[2] = 2, a[3] = 3, a[4] = 4, a[5] = 7, a[6] = 6, a[7] = 5, a[8] = 8, a[9] = 9;
    }
    int cnt = 0;
    for (int i = n % 10 + 1; i <= n; i++)
    {
        a[i] = a[i - 1] + mov[cnt % 10];
        cnt++;
    }
    for (int i = 1; i <= n; i++)
        cout << a[i] << " \n"[i == n];
}

K.Scheming Furry

题意:给出一个矩阵,狐狸每次操作可以交换两行,猫每次操作可以交换两列,狐狸先操作,谁先把数组变得有序(即按行优先顺序放置数字的顺序)谁获胜,如果谁知道自己无法获胜,则会尽可能不让另一个人获胜。

Solution

先考虑对于\(n>=3,m>=3\)的情况,容易发现如果狐狸不能一步完成,则猫永远也无法完成

\(n=2,m=2\)时,如果进行一次行操作和一次列操作能完成,则猫获胜,如果进行一次行操作能完成,则狐狸获胜

\(n=2,m>=3\)时,如果行操作次数与列操作次数奇偶性相同则猫获胜,反之平局

\(n>=3,n=2\)时,如果行操作次数与列操作次数奇偶性相反时狐狸获胜,反之平局

void solve()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> a[i][j];
        }
    }
    for (int i = 1; i <= m; i++)
    {
        for (int j = 2; j <= n; j++)
        {
            if (a[j][i] % m != a[j - 1][i] % m)
            {
                cout << "NSFW\n";
                return;
            }
        }
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 2; j <= m; j++)
        {
            if ((a[i][j] + m - 1) / m != (a[i][j - 1] + m - 1) / m)
            {
                cout << "NSFW\n";
                return;
            }
        }
    }

    int ans1 = 0, ans2 = 0;
    memset(vis1, 0, sizeof(vis1));
    memset(vis2, 0, sizeof(vis2));
    for (int i = 1; i <= n; i++)
    {
        if (!vis1[i])
        {
            int pos = i;
            while (!vis1[pos])
            {
                vis1[pos] = 1;
                int nxt = (a[pos][1] + m - 1) / m;
                pos = nxt;
                ans1++;
            }
            ans1--;
        }
    }

    for (int i = 1; i <= m; i++)
    {
        if (!vis2[i])
        {
            int pos = i;
            while (!vis2[pos])
            {
                vis2[pos] = 1;
                int nxt = (a[1][pos]) % m;
                if (nxt == 0)
                    nxt = m;
                pos = nxt;
                ans2++;
            }
            ans2--;
        }
    }

    if (ans1 == 1 && ans2 == 0)
    {
        cout << "FOX\n";
        return;
    }

    if (n >= 3 && m >= 3)
    {
        cout << "NSFW\n";
        return;
    }

    if (n == 2 && m == 2)
    {
        if (ans1 == 1 && ans2 == 1)
        {
            cout << "CAT\n";
        }
        else
        {
            cout << "FOX\n";
        }
        return;
    }
    else if (n == 2)
    {

        if ((ans1 & 1) == (ans2 & 1))
        {
            cout << "CAT\n";
            return;
        }
        else
        {
            cout << "NSFW\n";
            return;
        }
    }
    else if (m == 2)
    {

        if ((ans1 & 1) != (ans2 & 1))
        {
            cout << "FOX\n";
            return;
        }
        else
        {
            cout << "NSFW\n";
            return;
        }
    }
    else
        assert(0);
}

标签:back,cur,int,void,cin,多校,牛客,pos,2023
From: https://www.cnblogs.com/HikariFears/p/17633719.html

相关文章

  • [速报]2023-08-16: 发现Ubuntu网易云音乐几乎不能用了
    目录Ubuntu不能用Manjaro的也不能官网下载页替代方案yesplaymusicwineAUR仓库里的软件包Ubuntu不能用操作系统Ubuntu22.04.3网易云版本:iinetease-cloud-music1.2.1amd64Neteaseclou......
  • 2023“钉耙编程”中国大学生算法设计超级联赛(9)- 1003 Reasoning 题解
    题目翻译基本符号有一推理系统,其中有这些符号:括号\((\)和\()\);逻辑连接词\(\lnot\)和\(\rightarrow\);全称量词\(\forall\);变量\(u\simz\);常量\(a\sime\);函数\(f\simh\);谓词\(P\simT\)。这些符号是构成系统的基础,他们之间能够组合出一些其他概念:项(term......
  • 2023-2029全球铒YAG激光器行业调研及趋势分析报告
     2022年全球铒YAG激光器市场规模约亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近亿元,未来六年CAGR为%。从核心市场看,中国铒YAG激光器市场占据全球约%的市场份额,为全球最主要的消费市场之一,且增速高于全球。2022年市场规模约......
  • 2023-2029全球工业激光清洁行业调研及趋势分析报告
     2022年全球工业激光清洁市场规模约亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近亿元,未来六年CAGR为%。从核心市场看,中国工业激光清洁市场占据全球约%的市场份额,为全球最主要的消费市场之一,且增速高于全球。2022年市场规模......
  • 2023-2029全球激光清洗装置行业调研及趋势分析报告
     2022年全球激光清洗装置市场规模约亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近亿元,未来六年CAGR为%。从核心市场看,中国激光清洗装置市场占据全球约%的市场份额,为全球最主要的消费市场之一,且增速高于全球。2022年市场规模......
  • 2023-2029全球家用养生壶行业调研及趋势分析报告
     2022年全球家用养生壶市场规模约亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近亿元,未来六年CAGR为%。从核心市场看,中国家用养生壶市场占据全球约%的市场份额,为全球最主要的消费市场之一,且增速高于全球。2022年市场规模约亿......
  • 2023下半年产品经理国际认证NPDP8月19日线上开班
    产品经理国际资格认证NPDP是新产品开发方面的认证,集理论、方法与实践为一体的全方位的知识体系,为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。  【认证机构】 产品开发与管理协会(PDMA)成立于1979年,是全球范围内产品开发与管理专业人士最杰出的倡导者,协助个人、企业......
  • 2023年8月陕西/深圳软考中级系统集成项目管理工程师报名
    系统集成项目管理工程师是全国计算机技术与软件专业技术资格(水平)考试(简称软考)项目之一,是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试,既属于国家职业资格考试,又是职称资格考试。 系统集成项目管理工程师,属于软考三个级别中的“中级”。 考试合格者将颁发由中......
  • 2023年8月深圳面授CPDA数据分析师认证报名
    CPDA数据分析师认证是大数据方面的认证,助力数据分析人员打下扎实的数据分析基础知识功底,为入门数据分析保驾护航。帮助数据分析人员掌握系统化的数据分析思维和方法论,提升工作效率和决策能力,遇到问题能够举一反三,为大部分决策难题提供解决方案。帮助数据分析人员掌握几种通用的数据......
  • 2023年9月杭州/北京/深圳DAMA-CDGA/CDGP认证考试报名
    据DAMA中国官方网站消息,2023年度第三期DAMA中国CDGA和CDGP认证考试定于2023年9月23日举行。 报名通道现已开启,相关事宜通知如下: 考试科目: 数据治理工程师(CertifiedDataGovernanceAssociate,CDGA)数据治理专家(CertifiedDataGovernanceProfessional,CDGP) 考试时间: CDGA:2023......