文章目录

  • 一、AcWing 3956. 截断数组(中等)
    • 1. 实现思路
    • 2. 实现代码
  • 二、AcWing 3729. 改变数组元素(中等)
    • 1. 实现思路
    • 2. 实现代码
  • 三、AcWing 1460. 我在哪?(简单)
    • 1. 实现思路
    • 2. 实现代码
  • 四、AcWing 3768. 字符串删减(简单)
    • 1. 实现思路
    • 2. 实现代码
  • 五、AcWing 3777. 砖块(简单)
    • 1. 实现思路
    • 2. 实现代码

一、AcWing 3956. 截断数组(中等)

题目描述

给定一个长度为
n
n
n
的数组
a
1
,
a
2
,

,
a
n
a_{1},a_{2},…,a_{n}
a1,a2,,an

现在,要将该数组从中间截断,得到三个非空子数组。
要求,三个子数组内各元素之和都相等。
请问,共有多少种不同的截断方法?

输入格式

第一行包含整数
n
n
n

第二行包含
n
n
n
个整数
a
1
,
a
2
,

,
a
n
a_{1},a_{2},…,a_{n}
a1,a2,,an

输出格式

输出一个整数,表示截断方法数量。

数据范围

前六个测试点满足:
1

n

10
1≤n≤10
1n10

所有测试点满足:
1

n

1
5


10000

a
i

10000
1≤n≤10^{5},−10000≤a_{i}≤10000
1n10510000ai10000

输入样例 1

4
1 2 3 3

输出样例 1

1

输入样例 2

5
1 2 3 4 5

输出样例 2

0

输入样例 3

2
0 0

输出样例 3

0

具体实现

1. 实现思路

2. 实现代码

#include <bits/stdc++.h>
using namespace std;
int n;
int a[100005];
long long res=0,cnt=0;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int x=0;
		cin>>x;
		a[i]=a[i-1]+x;  //前缀和数组
	}
	if(a[n]%3!=0 || n<3)
	{
		cout<<"0"<<endl;
	}
	else
	{
		for(int j=2;j<n;j++)
		{
			if(a[j-1]==a[n]/3)
			{
				cnt++;
			}
			if(a[j]==a[n]/3*2)
			{
				res+=cnt;
			}
		}
		cout<<res;
	}
	return 0;
}

二、AcWing 3729. 改变数组元素(中等)

题目描述

给定一个空数组
V
V
V
和一个整数数组
a
1
,
a
2
,

,
a
n
a_{1},a_{2},…,a_{n}
a1,a2,,an

现在要对数组
V
V
V
进行
n
n
n
次操作。

i
i
i
次操作的具体流程如下:

注意:

输入格式

第一行包含整数
T
T
T
,表示共有
T
T
T
组测试数据。
每组数据第一行包含整数
n
n
n

第二行包含
n
n
n
个整数
a
1
,
a
2
,

,
a
n
a_{1},a_{2},…,a_{n}
a1,a2,,an

输出格式

每组数据输出一行结果,表示所有操作完成后的数组
V
V
V
,数组内元素之间用空格隔开。

数据范围


1

T

20000
1≤T≤20000
1T20000


1

n

2
×
1
5
1≤n≤2×10^{5}
1n2×105



a
i

n
0≤a_{i}≤n
0ain

保证一个测试点内所有
n
n
n
的和不超过
2
×
1
5
2×10^{5}
2×105

输入样例

3
6
0 3 0 0 1 3
10
0 0 0 1 0 5 0 0 0 2
3
0 0 0

输出样例

1 1 0 1 1 1
0 1 1 1 1 1 0 0 1 1
0 0 0

具体实现

1. 实现思路

2. 实现代码

#include <bits/stdc++.h>
using namespace std;
const int N=200010;
int n;
int b[N];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
	    cin>>n;
		memset(b,0,(n+1)*4);
		for(int i=1;i<=n;i++)
		{
			int x;
			cin>>x;
			x=min(x,i); //如果x大于i的话就更新成i,因为此时是将数组内的所有元素变为1 
			int l=i-x+1,r=i; 
			b[l]++;b[r+1]--;
		}
		for(int i=1;i<=n;i++)
		{
			b[i]+=b[i-1];
		}
		for(int i=1;i<=n;i++)
		{
			cout<<!!b[i]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

三、AcWing 1460. 我在哪?(简单)

题目描述

农夫约翰出门沿着马路散步,但是他现在发现自己可能迷路了!
沿路有一排共
N
N
N
个农场。
不幸的是农场并没有编号,这使得约翰难以分辨他在这条路上所处的位置。
然而,每个农场都沿路设有一个彩色的邮箱,所以约翰希望能够通过查看最近的几个邮箱的颜色来唯一确定他所在的位置。
每个邮箱的颜色用
A
.
.
Z
A..Z
A..Z
之间的一个字母来指定,所以沿着道路的
N
N
N
个邮箱的序列可以用一个长为
N
N
N
的由字母
A
.
.
Z
A..Z
A..Z
组成的字符串来表示。
某些邮箱可能会有相同的颜色。
约翰想要知道最小的
K
K
K
的值,使得他查看任意连续
K
K
K
个邮箱序列,他都可以唯一确定这一序列在道路上的位置。
例如,假设沿路的邮箱序列为 ABCDABC
约翰不能令
K
=
3
K=3
K=3
,因为如果他看到了 ABC,则沿路有两个这一连续颜色序列可能所在的位置。
最小可行的
K
K
K
的值为
K
=
4
K=4
K=4
,因为如果他查看任意连续
4
4
4
个邮箱,那么可得到的连续颜色序列可以唯一确定他在道路上的位置。

输入格式

输入的第一行包含
N
N
N
,第二行包含一个由
N
N
N
个字符组成的字符串,每个字符均在
A
.
.
Z
A..Z
A..Z
之内。

输出格式

输出一行,包含一个整数,为可以解决农夫约翰的问题的最小
K
K
K
值。

数据范围


1

N

100
1≤N≤100
1N100

输入样例

7
ABCDABC

输出样例

4

具体实现

1. 实现思路

2. 实现代码

#include <bits/stdc++.h>
using namespace std;
int n;
string str;
int main()
{
    cin >> n >> str;
    for (int k = 1; k <= n; k ++ )
    {
        bool flag = false;
        for (int i = 0; i + k - 1 < n; i ++ )
        {
            for (int j = i + 1; j + k - 1 < n; j ++ )
            {
                bool same = true;
                for (int u = 0; u < k; u ++ )
                    if (str[i + u] != str[j + u])
                    {
                        same = false;
                        break;
                    }
                if (same)
                {
                    flag = true;
                    break;
                }
            }
            if (flag) break;
        }
        if (!flag)
        {
            cout << k << endl;
            break;
        }
    }
    return 0;
}

四、AcWing 3768. 字符串删减(简单)

题目描述

给定一个由
n
n
n
个小写字母构成的字符串。
现在,需要删掉其中的一些字母,使得字符串中不存在连续三个或三个以上的
x
x
x

请问,最少需要删掉多少个字母?
如果字符串本来就不存在连续的三个或三个以上
x
x
x
,则无需删掉任何字母。

输入格式

第一行包含整数
n
n
n

第二行包含一个长度为
n
n
n
的由小写字母构成的字符串。

输出格式

输出最少需要删掉的字母个数。

数据范围


3

n

100
3≤n≤100
3n100

输入样例 1

6
xxxiii

输出样例 1

1

输入样例 2

5
xxoxx

输出样例 2

0

输入样例 3

10
xxxxxxxxxx

输出样例 3

8

具体实现

1. 实现思路

2. 实现代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	string s;
	cin>>n>>s;
	int res=0,cnt=0;
	for(int i=0;i<n;i++)
	{
		if(s[i]=='x')
		{
			cnt++;
			if(cnt==3)
			{
				cnt--;
				res++;
			}
		}
		else
		{
			cnt=0;
		}
	}
	cout<<res<<endl;
	return 0;
}

五、AcWing 3777. 砖块(简单)

题目描述


n
n
n
个砖块排成一排,从左到右编号依次为
1

n
1∼n
1n

每个砖块要么是黑色的,要么是白色的。
现在你可以进行以下操作若干次(可以是 0 次):
选择两个相邻的砖块,反转它们的颜色。(黑变白,白变黑)
你的目标是通过不超过
3
n
3n
3n
次操作,将所有砖块的颜色变得一致。

输入格式

第一行包含整数
T
T
T
,表示共有
T
T
T
组测试数据。
每组数据第一行包含一个整数
n
n
n

第二行包含一个长度为
n
n
n
的字符串
s
s
s
。其中的每个字符都是 WB,如果第
i
i
i
个字符是 W,则表示第
i
i
i
号砖块是白色的,如果第
i
i
i
个字符是 B,则表示第
i
i
i
个砖块是黑色的。

输出格式

每组数据,如果无解则输出一行

1
−1
1

否则,首先输出一行
k
k
k
,表示需要的操作次数。
如果
k
>
k>0
k>0
,则还需再输出一行
k
k
k
个整数,
p
1
,
p
2
,

,
p
k
p_{1},p_{2},…,p_{k}
p1,p2,,pk
。其中
p
i
p_{i}
pi
表示第
i
i
i
次操作,选中的砖块为
p
i
p_{i}
pi

p
i
+
1
p_{i+1}
pi+1
号砖块。
如果方案不唯一,则输出任意合理方案即可。

数据范围


1

T

10
1≤T≤10
1T10


2

n

200
2≤n≤200
2n200

输入样例

4
8
BWWWWWWB
4
BWBB
5
WWWWW
3
BWB

输出样例

3
6 2 4
-1
0
2
2 1

具体实现

1. 实现思路

2. 实现代码

#include <bits/stdc++.h>
using namespace std;
int n;
string str;
void update(char &c)
{
	if(c=='W')
	{
		c='B';
	}
	else
	{
		c='W';
	}
}
bool check(char c)
{
	vector<int>res;
	string s=str;
	for(int i=0;i<n-1;i++)
	{
		if(s[i]!=c)
		{
			update(s[i]);
			update(s[i+1]);
			res.push_back(i+1); //字符串从0开始,题目中从1开始
		}
	}
	if(s.back()!=c)
	{
		return false;
	}
	cout<<res.size()<<endl;
	for(int x=0;x<res.size();x++)
	{
		cout<<res[x]<<' ';
	}
	if(res.size()!=0)
	{
		cout<<endl;
	}
	return true;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		cin>>n>>str;
		if(!check('B')&&!check('W'))
		{
			cout<<"-1"<<endl;
		}
	}
	return 0;
}

发表回复