CodeForces 1137B(2020.3.8训练F题)

题目:
The new camp by widely-known over the country Spring Programming Camp is going to start soon. Hence, all the team of friendly curators and teachers started composing the camp’s schedule. After some continuous discussion, they came up with a schedule s, which can be represented as a binary string, in which the i-th symbol is ‘1’ if students will write the contest in the i-th day and ‘0’ if they will have a day off.

At the last moment Gleb said that the camp will be the most productive if it runs with the schedule t (which can be described in the same format as schedule s). Since the number of days in the current may be different from number of days in schedule t, Gleb required that the camp’s schedule must be altered so that the number of occurrences of t in it as a substring is maximum possible. At the same time, the number of contest days and days off shouldn’t change, only their order may change.

Could you rearrange the schedule in the best possible way?

Input
The first line contains string s (1⩽|s|⩽500000), denoting the current project of the camp’s schedule.

The second line contains string t (1⩽|t|⩽500000), denoting the optimal schedule according to Gleb.

Strings s and t contain characters ‘0’ and ‘1’ only.

Output
In the only line print the schedule having the largest number of substrings equal to t. Printed schedule should consist of characters ‘0’ and ‘1’ only and the number of zeros should be equal to the number of zeros in s and the number of ones should be equal to the number of ones in s.

In case there multiple optimal schedules, print any of them.

题意:已知两个二进制编码的字符串,即每个位置只有0或1两种情况,第一个字符串可内部任意调换顺序,使之能与第二个字符串匹配次数最多,如果有多重结果,随意输出一种即可

理解:这题刚拿到手切不可拍脑瓜全部当成一般计数题做,要用next数组的…,肯定会wa,别问我怎么知道的…

看到匹配这个字眼,想想会出现首尾重叠即最大前后缀的情况 CodeForces 1137B(2020.3.8训练F题)_第1张图片

为了使二串匹配次数最多,先分别统计一下一串的0和1的个数,比如记作n1,n2,在满足n1大于0,n2大于0的前提下,尽可能多的重复凑出二串的组合,再考虑前后缀重叠的情况,所以我们要先对二串进行求next数组操作,二串的长度减去最长公共前后缀后就是最小的重复单元,输出一个,对应的n1或n2减一,当n1或n2到达0后,把多出的另一部分直接输出出来就可以了(比如代表0个数的n2=0后,就将剩下的n1个1输出就行了)

ac代码如下:

#include
#include
using namespace std;

const int maxn=500005;
int nxt[maxn];
int mp[2];
char s1[maxn],s2[maxn];

void getnext(char s[], int len)
{
	nxt[1] = 0;
	
	for (int i = 2, j = 0; i <= len; i++)
	{
		while (s[j + 1] != s[i] && j != 0)
			j = nxt[j];
		if (s[j + 1] == s[i]) j++;
		nxt[i]=j;
	}

}

int main()
{
	string ans = "";
	scanf("%s%s", s1 + 1, s2 + 1);
	int len1 = strlen(s1 + 1);
	int len2 = strlen(s2 + 1);
	
	for (int i = 1; i <= len1; i++)
	{
		mp[s1[i] - '0']++;
	}

	getnext(s2, len2);
	
	int renum = nxt[len2];

	int len = len2 - renum;

	
	for (int i = 1; i <= len; i++)
	{
		if (mp[s2[i] - '0'])
		{
			mp[s2[i] - '0']--;
			cout << s2[i];
		}
		else 
			break;
		
		if(i == len)
			i = 0;
			
	}
	
	while (mp[1]--)
	{
		cout << 1;
	}
	while (mp[0]--)
	{
		cout << 0;
	}
	cout << endl;
}

你可能感兴趣的:(CodeForces 1137B(2020.3.8训练F题))