【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; }
相关文章推荐
- 【hackerrank】World CodeSprint 11 T4
- [hackerrank]Weekly Challenges - Week 11
- 【Hackerrank】Delete duplicate-value nodes from a sorted linked list
- 【hackerrank】Insertion Sort Advanced Analysis
- hackerrank Roads and Libraries(DFS/并查集)
- hackerrank The Coin Change Problem(dp)
- [hackerrank]Walking the Longest Path (Approximation Problem)
- 【Hacker Rank】03.Python If-Else
- HackerRank Week of Code 26
- Hackerrank Hard Homework
- HackerRank "Components in a graph"
- HackerRank难题记录
- HackerRank Weekly Challenges - Week 6: Consecutive Subsequences 你有余我也有余
- 【HackerRank】The Love-Letter Mystery
- [hackerrank]Self-Driving Bus
- 【HackerRank】Sherlock and Array
- *[hackerrank]ACM ICPC Team
- HackerRank "Lena Sort"
- HackerRank Hiring Contest - C The Simplest Sum
- hackerrank初级篇之Diagonal Difference