今天主要是进行了测试,留下两个比较有意义的题目。
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
A 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.
A 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.
A 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);
}
}
总结:
今天的测试,总体来说还可以,但是最后那两个题我明明是有思路的,明明可以做出来的,但是没有做出来,但是心态也有点炸,所以后面半个小时有点浪费了。