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");
    }
}

 

posted @ 2022-02-18 15:38  Xu_brezza  阅读(79)  评论(0编辑  收藏  举报