AcWing第32场周赛题解

第32场周赛活动链接

problem.A AcWing4203 寻找子串

本题十分简单,首先看数据范围n:1~100,所以可以直接暴力求解
从头至尾走一遍字符串,检查是否有"0000000"或者"1111111"即可

代码

#include <iostream>

using namespace std;

int main()
{
    string tmp;
    cin>>tmp;
    bool flag=false;
    
    int len=tmp.size()-6;
    for(int i=0;i<len;i++)
    {
        string test=tmp.substr(i,7);
        if(test=="0000000"||test=="1111111")
        {
            flag=true;
            break;
        }
    }
    
    if(flag) cout<<"YES";
    else cout<<"NO";
    
    return 0;
}

problem.B AcWing4204 构造矩阵

本题借用 @灵茶山艾府 的思路,他的思路相当简洁,可以直接构造出满足题目要求的矩阵

先构造如下符合部分要求的 $(n-1)\times (n-1)$ 的矩阵:

$
\begin{matrix}
1 & 2 & 3 & \cdots & n-1 \\
2 & 3 & 4 & \cdots & 1 \\
3 & 4 & 5 & \cdots & 2 \\
\vdots & \vdots & \vdots & \vdots & \vdots \\
n-1 & 1 & 2 & \cdots & n-2 \\
\end{matrix}
$

然后在最右边增加一列,最下边增加一行,将主对角线上数字移动到其所在行列,并将主对角线上的数字改成 $0$,就可以得到如下符合题目要求的 $n\times n$ 的矩阵:

$
\begin{matrix}
0 & 2 & 3 & \cdots & n-1 & 1 \\
2 & 0 & 4 & \cdots & 1 & 3 \\
3 & 4 & 0 & \cdots & 2 & 5 \\
\vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\
n-1 & 1 & 2 & \cdots & 0 & n-2 \\
1 & 3 & 5 & \cdots & n-2 & 0
\end{matrix}
$

接下来计算 $(n-1)\times (n-1)$ 的矩阵中各个元素的值(行为 $i$,列为 $j$,下标从 $0$ 开始):

  • 非主对角线上的元素可以用 $(i+j)\bmod (n-1)+1$ 来表示;
  • 主对角线上的元素可以用 $2i\bmod (n-1)+1$ 来表示,由于其在 $n\times n$ 的矩阵中被移到了最后一行(列),在计算时变成 $2(i+j-(n-1))\bmod (n-1)+1=2(i+j)\bmod (n-1)+1$。

代码

#include <iostream>

using namespace std;

int n;

int main()
{
    cin>>n;
    
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(i==j) cout<<"0 ";
            else if(i<n-1 && j<n-1) cout<<(i+j)%(n-1)+1<<' ';
            else cout<<2*(i+j)%(n-1)+1<<' ';
        }
        cout<<endl;
    }
    
    return 0;
}

problem.C AcWing4205 树的增边

思路:
先利用染色法将所有点染色为1或者2,表示其在二部图的哪一侧,确定好两侧的颜色后统计点的数量,显然我们在增加边的时候,不能改变点的位置,这些点事实上已经被分别配好位置了。
这个时候我们计算这个二部图最大的边数,即两侧点数之积,题目给的树一定是这个最大二部图的子集,我们再拿点数之积减去总边数(n-1),即可得到答案。

代码

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 300010, M = 300010;

typedef long long LL;

int n;
int h[N], e[M], ne[M], idx;
int color[N];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

bool dfs(int u, int c)
{
    color[u] = c;

    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!color[j])
        {
            if (!dfs(j, 3 - c)) return false;
        }
        else if (color[j] == c) return false;
    }

    return true;
}

int main()
{
    scanf("%d", &n);

    memset(h, -1, sizeof h);

    for(int i=0;i<n-1;i++)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b), add(b, a);
    }
    
    int count=0;
    
    bool flag = true;
    for (int i = 1; i <= n; i ++ )
        if (!color[i])
        {
            if (!dfs(i, 1))
            {
                flag = false;
                break;
            }
        }
        
    for(int i=1;i<=n;i++)
    {
        if(color[i]==1) count++;
    }

    LL l=count,r=n-count;
    cout<<l*r-(n-1);

    return 0;
}
posted @ 2022-01-02 09:23  泝涉江潭  阅读(30)  评论(0)    收藏  举报