Luogu8248 solution

Problem

link->https://www.luogu.com.cn/problem/P8248

Solution

按题意直接构造即可:每次扩展时循环 \(1,2,3,4\),判断是否可以添加(循环 \(len\)\(1\)\(\lfloor\frac{i}{2}\rfloor\),判断每个 \(a_{i-len+1...i}\)\(a_{i-len\times 2+1...i-len}\) 是否相同,如有相同,则回溯至上一步)。

Code

#include<bits/stdc++.h>
#define pd push_back
#define pb pop_back
#define mk make_pair
//#define int long long
#define PII pair<int,int>
#define _for(a,b,c) for(int a=b;a<=c;a++)
#define _rep(a,b,c) for(int a=b;a>=c;a--)
using namespace std;
template <typename T> inline void read(T& x) {
	x=0; T f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch&15); ch=getchar(); }
	x=x*f;
	return;
}
template <typename T,typename ...Arg> inline void read(T& x,Arg& ...arg){
	read(x); read(arg...);
}
int power(int a,int b) {
	int ans=1;
	do {
		if(b&1) ans*=a; a*=a;
	} while(b>>=1);
	return ans;
}
const int N=505;
int n,v[N],tot;
bool used[4];
bool check(int l1,int r1,int l2,int r2) { //判断 a[l1~r1] 是否于 a[l2~r2] 相同
	int k=0;
	while(l1+k<=r1&&l2+k<=r2) {
		if(v[l1+k]!=v[l2+k])
			return false;
		++k;
	}
	return true;
}
signed main() {
	read(n);
	while(tot<n) {
		printf("v.size=%d\n",tot);
		_for(i,1,4) { //循环扩展元素
			if(tot==n) break;
			printf("i=%d\n",i);
			v[++tot]=i;
			bool flag=0; //flag=0 表示可以拓展,flag=1 表示不可以拓展
			_for(len,1,tot/2) //循环每个 len
				flag|=check(tot-len+1,tot,tot-len*2+1,tot-len);
			if(flag) {
				--tot; printf("pop\n");
			}
		}
	}
	_for(i,1,tot)
		printf("%d ",v[i]);
	return 0;
}
posted @ 2022-08-01 14:20  lsj2009  阅读(44)  评论(0)    收藏  举报