题面:https://ac.nowcoder.com/acm/contest/33189/H
分析:
为使周长最小,可以先求出积木的总面积S,然后众所周知,在长方形中长与宽越接近周 长越小
可从w=
S
\sqrt{S}
S开始向上枚举,直到找到一组合解,即,此时h=S/w
找到了最小周长,对于构造矩形,我们可以采用贪心的方法(尽量选大的,因为小的比较灵活,应到其他积木都无法放时再放)重复h次
到此,这道题就结束了
代码:
#include<bits/stdc++.h>
using namespace std;
const int MXN=107;
int a[MXN];
struct Node{
int lx,ly,rx,ry;
}g[MXN*MXN];
int main(){
ios::sync_with_stdio(false);
int T,n,S,w,h,sum,cnt,i,j;
cin>>T;
while(T--){
S=0;
cnt=0;
cin>>n;
for(i=1;i<=n;i++){
S+=i*(n-i+1);
a[i]=n-i+1;
}
for(i=sqrt(S);i>=1;i--){
if(S%i==0){
w=S/i;
h=i;
break;
}
}
for(i=1;i<=h;i++){
sum=0; j=n;
while(sum!=w){
while(a[j]>0 && sum+j<=w){
cnt++;
g[cnt].lx=sum; g[cnt].ly=i-1;
g[cnt].rx=sum+j; g[cnt].ry=i;
sum+=j;
a[j]--;
}
if(sum==w){
break;
}
j--;
}
}
cout<<2*(w+h)<<"\n";
for(i=1;i<=cnt;i++){
cout<<g[i].lx<<" "<<g[i].ly<<" "<<g[i].rx<<" "<<g[i].ry<<"\n";
}
}
}