2023.2.6(总结)

今天主要是进行了测试,留下两个比较有意义的题目。

C - Count Connected Components Editorial

 / 


Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 300300 points

Problem Statement

You are given a simple undirected graph with NN vertices numbered 11 to NN and MM edges numbered 11 to MM. Edge ii connects vertex u_iui​ and vertex v_ivi​.
Find the number of connected components in this graph.

Notes

simple undirected graph is a graph that is simple and has undirected edges.
A graph is simple if and only if it has no self-loop or multi-edge.

subgraph of a graph is a graph formed from some of the vertices and edges of that graph.
A graph is connected if and only if one can travel between every pair of vertices via edges.
connected component is a connected subgraph that is not part of any larger connected subgraph.

Constraints

  • 1 \leq N \leq 1001≤N≤100
  • 0 \leq M \leq \frac{N(N - 1)}{2}0≤M≤2N(N−1)​
  • 1 \leq u_i, v_i \leq N1≤ui​,vi​≤N
  • The given graph is simple.
  • All values in the input are integers.

Input

The input is given from Standard Input in the following format:

NN MM
u_1u1​ v_1v1​
u_2u2​ v_2v2​
\vdots⋮
u_MuM​ v_MvM​

Output

Print the answer.


Sample Input 1 Copy

Copy

5 3
1 2
1 3
4 5

Sample Output 1 Copy

Copy

2

The given graph contains the following two connected components:

  • a subgraph formed from vertices 11, 22, 33, and edges 11, 22;
  • a subgraph formed from vertices 44, 55, and edge 33.


Sample Input 2 Copy

Copy

5 0

Sample Output 2 Copy

Copy

5

Sample Input 3 Copy

Copy

4 6
1 2
1 3
1 4
2 3
2 4
3 4

Sample Output 3 Copy

Copy

1

分析:

1,留下这个题的意义是因为它涉及到了我们之前学过的内容,图。一道利用并查集的纯模板题。

代码如下:

#include<stdio.h>
#include<math.h>
#include<string.h>
int pre[105];

int f(int x)
{
    if(pre[x]!=x)
    pre[x]=f(pre[x]);
    return pre[x];
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    pre[i]=i;
    for(int i=0;i<m;i++)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        pre[f(l)]=f(r);
    }
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        if(f(i)==i)
        sum++;
    }
    printf("%d",sum);
}

B. Paranoid String

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Let's call a binary string TT of length mm indexed from 11 to mm paranoid if we can obtain a string of length 11 by performing the following two kinds of operations m−1m−1 times in any order :

  • Select any substring of TT that is equal to 01, and then replace it with 1.
  • Select any substring of TT that is equal to 10, and then replace it with 0.

    For example, if T=T= 001, we can select the substring [T2T3][T2T3] and perform the first operation. So we obtain T=T= 01.

You are given a binary string SS of length nn indexed from 11 to nn. Find the number of pairs of integers (l,r)(l,r) 1≤l≤r≤n1≤l≤r≤n such that S[l…r]S[l…r] (the substring of SS from ll to rr) is a paranoid string.

Input

The first line contains an integer tt (1≤t≤10001≤t≤1000) — the number of test cases. The description of test cases follows.

The first line of each test case contains a single integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the size of SS.

The second line of each test case contains a binary string SS of nn characters S1S2…SnS1S2…Sn. (Si=Si= 0 or Si=Si= 1 for each 1≤i≤n1≤i≤n)

It is guaranteed that the sum of nn over all test cases doesn't exceed 2⋅1052⋅105.

Output

For each test case, output the number of pairs of integers (l,r)(l,r) 1≤l≤r≤n1≤l≤r≤n such that S[l…r]S[l…r] (the substring of SS from ll to rr) is a paranoid string.

Example

input

Copy

 

5

1

1

2

01

3

100

4

1001

5

11111

output

Copy

1
3
4
8
5

Note

In the first sample, SS already has length 11 and doesn't need any operations.

In the second sample, all substrings of SS are paranoid. For the entire string, it's enough to perform the first operation.

In the third sample, all substrings of SS are paranoid except [S2S3][S2S3], because we can't perform any operations on it, and [S1S2S3][S1S2S3] (the entire string).

分析:

1,首先由题目很容易看出,每次操作也就是相当于把不同的两个字符删去左边那个留下右边那一个。

2,枚举以s[j]字符为结尾的子串,如果s[j]==s[j-1],也就是说这两个字符无法相消,那么以s[j]为结尾的前部分子串更无法消去此时答案数+1,因为本身s[j]这个字符就可以看作长度为1的字符串。

3,如果s[j]!=s[j-1],可以证明,此时以s[j]为结尾的所有子串都会被消去只剩s[j],设一个串xxxxx?01,首先我们知道题目的意思就是两个字符不同时保留右边那个。 

4, 如果当 " ?" 不同于0 .那么 "?" 在0的左边,且不相同,则可以被0消去。剩下字符串 xxxxx01  

 5, 如果 "?" 和0相同,也就是说 "?" 和1不同。那么1可以先消去0,原串变成xxxxx?1,因为此时?和1不同,也可以看做xxxxx01。

6.所以不管哪种情况都能变成结尾为s[j-1]+s[j]的情况,接下来继续这样讨论直到消去j前面的所有字符。所以子串s[j-j],s[j-1 - j],s[j-2 - j]...s[1-j]都可以被消去,此时答案+j,因为以s[j]结尾的子串 有j个。

代码如下:

#include<stdio.h>
#include<math.h>
#include<string.h>
char a[200005];
int main()
{
    int t;
    scanf("%d",&t);
    for(int i=0;i<t;i++)
    {
        int n;
        scanf("%d",&n);
        scanf("%s",a);
        long long sum=0;
        for(int j=1;j<n;j++)
        {
            if(a[j-1]!=a[j])
            sum+=j;
        }
        printf("%lld\n",sum+n);
    }
}

总结:

今天的测试,总体来说还可以,但是最后那两个题我明明是有思路的,明明可以做出来的,但是没有做出来,但是心态也有点炸,所以后面半个小时有点浪费了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值