ybtoj折纸问题
dfs 裸题,大力搜索就行。。。
题里说只能向左翻,但是你可以手动分块一下,对于翻折点在右半部分的,直接翻,对于左半部分的,等价于把左边翻到右边再对称,而这已经在判断的时候检查了,所以翻折长度控制在了$\frac{len}{2}$ 所以复杂度会优一些。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=(a);i<=(b);++i) #define Rep(i,a,b) for(int i=(a);i<(b);++i) #define rrep(i,a,b) for(int i=(a);i>=(b);--i) using namespace std; template <typename T> inline void read(T &x){ x=0;char ch=getchar();bool f=0; while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); if(f)x=-x; } template <typename T,typename ...Args> inline void read(T &tmp,Args &...tmps){read(tmp);read(tmps...);} const int N = 20; int a[N],n,m,b[N]; bool dfs(int l,int r){ if(r - l + 1 < m)return 0; if(r - l + 1 == m){ int flag = 1; rep(i,l,r)if(a[i] != b[i-l+1])flag = 0; if(flag)return 1; flag = 1; rep(i,1,m)if(a[r-i+1] != b[i])flag = 0; return flag; } int c[N],res = 0; memcpy(c,a,sizeof(a)); rep(i,l,r-1){ if(i - l + 1 > r - i){ int x = i,y = i + 1; for(;y<=r;x--,y++)a[x] += a[y]; res |= dfs(l,i); } else{ int x = i,y = i + 1; for(;x>=l;x--,y++)a[y] += a[x]; res |= dfs(i+1,r); } memcpy(a,c,sizeof(a)); } return res; } signed main(){ while(scanf("%d",&n) != EOF){ rep(i,1,n)read(a[i]); read(m); rep(i,1,m)read(b[i]); puts(dfs(1,n) ? "S" : "N"); } }