【题解】uva1602(同sdoj3208)(2018-08-14集训T2)搜索+判重

UVA题目链接 sdoj题目链接
代码参考了大佬博客
比赛时想到了怎么判重,但是有些细节地方不好写,考场暴力居然打了50……

#include<cstdio>
#include<set>
#include<algorithm>
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
#define _for(i,a,b) for(int i=(a);i<(b);i++)
using namespace std;
int ans[15][15][15]; 
struct node{//定义一个格子 
    int x,y;
    node(int _x,int _y){x=_x,y=_y;}
    bool operator <(const node&rhs)const{
    return x<rhs.x||(x==rhs.x&&y<rhs.y);}
};
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
set<node>pos;//保存方案 
set<set<node> >poss[15];//pos[i]存体积为i的情况 
set<node> Move(const set<node>&tmp)//全部平移到左上角 
{
    set<node>ret;
    int minx=tmp.begin()->x;
    int miny=tmp.begin()->y;
    for(set<node>::iterator it=tmp.begin();it!=tmp.end();it++)
    minx=min(minx,it->x),miny=min(miny,it->y);
    for(set<node>::iterator it=tmp.begin();it!=tmp.end();it++)
    ret.insert(node(it->x-minx,it->y-miny));
    return ret;
}
set<node> Rotate(const set<node>&tmp)//旋转 
{
    set<node>ret;
    for(set<node>::iterator it=tmp.begin();it!=tmp.end();it++)
    ret.insert(node(it->y,-(it->x)));
    return Move(ret);
}
set<node> Flip(const set<node>&tmp)//翻转 
{
    set<node>ret;
    for(set<node>::iterator it=tmp.begin();it!=tmp.end();it++)
    ret.insert(node(it->x,-(it->y)));
    return Move(ret);
}
void dfs(const set<node>&s,const node&tmp)
{
    set<node>newnode=s;
    newnode.insert(tmp);
    newnode=Move(newnode);
    _for(i,0,4)//4次翻转 
    {
        if(poss[newnode.size()].count(newnode))return;//这种情况已经存在了
        newnode=Rotate(newnode); 
    }
    newnode=Flip(newnode);
    _for(i,0,4)
    {
        if(poss[newnode.size()].count(newnode))return;
        newnode=Rotate(newnode);
    }
    poss[newnode.size()].insert(newnode);
}
void Init()
{
    pos.insert(node(0,0));
    poss[1].insert(pos);
    _rep(k,2,10)//枚举体积为k的情况 
        for(set<set<node> >::iterator its=poss[k-1].begin();its!=poss[k-1].end();its++)//先取出每种k-1体积的姿势 
            for(set<node>::iterator it=(*its).begin();it!=(*its).end();it++)//枚举里面的方格
                _for(i,0,4)
                {
                    int nx=it->x+dx[i];
                    int ny=it->y+dy[i];
                    node tmp(nx,ny);
                    if(!its->count(tmp))dfs(*its,tmp);
                } 
    _rep(k,1,10)_rep(m,1,10)_rep(n,1,10)
    {
        int cnt=0;
        for(set<set<node> >::iterator its=poss[k].begin();its!=poss[k].end();its++)
        {
            int maxx=0,maxy=0;
            for(set<node>::iterator it=(*its).begin();it!=(*its).end();it++)
                maxx=max(maxx,it->x),maxy=max(maxy,it->y);
            if(min(maxx,maxy)<min(m,n)&&max(maxx,maxy)<max(m,n))
                cnt++;//放得下 
        }
        ans[k][m][n]=cnt;
    }
}
int main()
{
    int m,n,k;  
    Init();
    while(~scanf("%d%d%d",&k,&m,&n))
        printf("%d\n",ans[k][m][n]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41958841/article/details/81674234
今日推荐