【hackerrank】World CodeSprint 11 T6

题目大意

把n个俄罗斯方块一样的东西拼成一个长方形,可以旋转,不能翻转。
得到的长方形的面积和最优解越接近得分越多。

数据范围
n<=1500
n个方块所占总个数不超过25000。

解题思路

只会暴力了,48分(满分85)。
其实就是依次暴力枚举一个块放在哪里,同时卡一下时。
用vector可以省去一些麻烦。
说一下代码中的random:
若是按原次序枚举位置,那就只能把当前块紧挨着前面几块来放,而变换放下去的顺序可以解决这个问题。

#include
#include
#include
#include
#include
#define maxn 1506
#define maxp 5006
#define maxs 25003
#define fr(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const ll lim2=3e8;

struct piec
{
    int x,y;
} s,ans;
bool operator <(piec a,piec b)
{
    return 1ll*a.x*a.y<1ll*b.x*b.y;
}
vector pie[maxn][5];
int i,j,k,n,xx,yy,lim,seq[maxn],tot[maxn],sans[maxp][maxp],ma[maxp][maxp];
void turn(int z,int ci)
{
    int i,j,x=1 << 30,y=1 << 30;
    fr(i,1,tot[z])
    {
        x=min(x,pie[z][ci][i-1].x);
        y=min(y,pie[z][ci][i-1].y);
    }
    fr(i,1,tot[z])
    {
        pie[z][ci][i-1].x-=x;
        pie[z][ci][i-1].y-=y;
    }
    return;
}
bool check(int w,int v,int x,int y)
{
    int i;
    fr(i,1,tot[x])
    {
        ++lim;
        if (ma[w+pie[x][y][i-1].x][v+pie[x][y][i-1].y]!=0)
            return 0;
    }
    return 1;
}
void write(int w,int v,int x,int y,int z,piec &t)
{
    int i;
    fr(i,1,tot[x])
    {
        ++lim;
        ma[w+pie[x][y][i-1].x][v+pie[x][y][i-1].y]=z;
        t.x=max(t.x,w+pie[x][y][i-1].x);
        t.y=max(t.y,v+pie[x][y][i-1].y);
    }
    return;
}
void make(int x,piec s)
{
    if (ans<s) return;
    if (lim>lim2) return;
    if (x==n+1)
    {
        if (sint i,j;
            ans=s;
            fr(i,1,ans.x)
                fr(j,1,ans.y)
                    sans[i][j]=ma[i][j];
        }
        return;
    }
    int i,j,k;
    piec t=s;
    fr(i,1,s.x+1)
        fr(j,1,s.y+1)
        {
            fr(k,1,4)
            {
                if (check(i,j,seq[x],k))
                {
                    write(i,j,seq[x],k,seq[x],t);
                    if (tx+1,t);
                    if (lim>lim2) return;
                    write(i,j,seq[x],k,0,t);
                }
                t=s;
            }
        }
    return;
}
int main()
{
    srand(time(0));
    scanf("%d",&n);
    int ww=0,vv=0;
    piec tt;
    fr(i,1,n)
    {
        scanf("%d",&tot[i]);
        fr(j,1,tot[i])
        {
            scanf("%d%d",&xx,&yy);
            tt.x=xx,tt.y=yy;
            pie[i][1].push_back(tt);
            ww=pie[i][1][j-1].x,vv=pie[i][1][j-1].y;
        }
        fr(j,2,4)
        {
            fr(k,1,tot[i]) 
            {
                ww=pie[i][j-1][k-1].x;
                vv=pie[i][j-1][k-1].y;
                tt.x=ww,tt.y=vv;
                pie[i][j].push_back(tt);
                swap(pie[i][j][k-1].x,pie[i][j][k-1].y);
                pie[i][j][k-1].x=-pie[i][j][k-1].x;
            }
            turn(i,j);
        }
    }
    fr(i,1,n) seq[i]=i;
    ans.x=ans.y=1 << 30;
    s.x=s.y=0;
    while (lim1,seq+n+1);
        make(1,s);
    }
    printf("%d %d\n",ans.x,ans.y);
    fr(i,1,ans.x)
    {
        fr(j,1,ans.y) printf("%d ",sans[i][j]);
        printf("\n");
    }
    return 0;
}

你可能感兴趣的:(hackerrank)