JZOJ 2020.07.28【NOIP提高组】模拟

2020.07.28【NOIP提高组】模拟

考试时状态不好,暴力不想打
结束前勉勉强强骗点分
已经不想说什么了······

\(T1\) 复制&粘贴2
逆推答案,枚举 \(k\),分类讨论

\(T2\) 愉快的logo设计
暴力计算贡献改为前缀和,把原串复制一片,把目标串分成连续的多块,记录开头结尾,根据前缀和算成功匹配的个数,取最大的即可

\(T3\) Flower 特难的题,见我另一篇,这里不展开叙述

\(T4\) 有趣的有趣的家庭菜园 还可以,见我另一篇,这里不展开叙述

前两题代码:

\(Code1\)

#include<cstdio>
#include<cstring>
using namespace std;

const int N = 2e5 + 5;
int k , m , n , x[N] , y[N] , z[N];
char s[N];

int main()
{
	freopen("copypaste.in" , "r" , stdin);
	freopen("copypaste.out" , "w" , stdout);
	scanf("%d%d%s%d" , &k , &m , s , &n);
	for(register int i = 1; i <= n; i++) scanf("%d%d%d" , &x[i] , &y[i] , &z[i]);
	int len = strlen(s);
	for(register int i = len; i; i--) s[i] = s[i - 1];
	for(register int i = 1; i <= k; i++)
	{
		int ans = i;
		for(register int j = n; j; j--)
		{
			if (z[j] + y[j] - x[j] < ans) ans = ans - (y[j] - x[j]);
			else if (ans > z[j]) ans = ans - z[j] + x[j];
		}
		printf("%c" , s[ans]);
	}
}

\(Code2\)

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

const int N = 5000005;
int k , ans = N , tot = 0 , num[5][N];
char s[N] , str[13][N];

struct node{
	int l , r , s;
}fl[N];

int main()
{
	freopen("logo.in" , "r" , stdin);
	freopen("logo.out" , "w" , stdout);
	scanf("%d%s" , &k , s);
	
	int p = 1;
	str[0][0] = '0';
	for(register int i = 1; i <= k; i++)
	{
		for(register int j = 1; j <= p; j++) str[i][j - 1] = 'J' , str[i][j + p - 1] = 'O' , str[i][j + p * 2 - 1] = 'I';
		for(register int j = 3 * p; j < 4 * p; j++) str[i][j] = str[i - 1][j - 3 * p];
		p *= 4;
	}
	for(register int i = 0; i < p - 1; i++) 
	{
		int j = i;
		fl[++tot].l = i;
		fl[tot].s = str[k][i] == 'J' ? 1 : (str[k][i] == 'O' ? 2 : 3);
		while (str[k][j] == str[k][j + 1]) j++;
		fl[tot].r = j;
		i = j;
	}
	
	p = strlen(s);
	for(register int i = p; i <= p * 2 - 1; i++) s[i] = s[i - p];
	for(register int i = 0; i <= p * 2 - 1; i++) 
	{
		int x = s[i] == 'J' ? 1 : (s[i] == 'O' ? 2 : 3);
		if (i != 0) 
		{
			num[1][i] = num[1][i - 1];
			num[2][i] = num[2][i - 1];
			num[3][i] = num[3][i - 1];
		}
		num[x][i]++;
	}
	
	for(register int i = 0; i < p; i++)
	{
		int x = 0;
		for(register int j = 1; j <= tot; j++) 		
			x += fl[j].l + i != 0 ? num[fl[j].s][fl[j].r + i] - num[fl[j].s][fl[j].l + i - 1] : num[fl[j].s][fl[j].r + i];
		ans = min(ans , p - x);
	}	
	printf("%d" , ans - 1);	
}
posted @ 2020-07-28 18:08  leiyuanze  阅读(90)  评论(0编辑  收藏  举报