您的位置:首页 > 其它

【hackerrank】World CodeSprint 11 T6

2017-06-03 22:13 351 查看

题目大意

把n个俄罗斯方块一样的东西拼成一个长方形,可以旋转,不能翻转。

得到的长方形的面积和最优解越接近得分越多。

数据范围

n<=1500

n个方块所占总个数不超过25000。

解题思路

只会暴力了,48分(满分85)。

其实就是依次暴力枚举一个块放在哪里,同时卡一下时。

用vector可以省去一些麻烦。

说一下代码中的random:

若是按原次序枚举位置,那就只能把当前块紧挨着前面几块来放,而变换放下去的顺序可以解决这个问题。

#include<ctime>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#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<piec> 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 (s<ans)
{
int 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 (t<ans) make(x+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 (lim<lim2)
{
random_shuffle(seq+1,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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息