首页 > 其他分享 >ACdream 1429 Rectangular Polygon

ACdream 1429 Rectangular Polygon

时间:2022-11-09 18:33:56浏览次数:41  
标签:use polygon Johnny 1429 sticks int Polygon ACdream must


Description



      A rectangular polygon is a polygon whose edges are all parallel to the coordinate axes. The polygon must have a single, non-intersecting boundary. No two adjacent sides must be parallel. 

      Johnny has several sticks of various lengths. He would like to construct a rectangular polygon. He is planning to use sticks as horizontal edges of the polygon, and draw vertical edges with a pen. 

Johnny wonders, how many sticks he can use. Help him, find the maximal number of sticks that Johnny can use. He will use sticks only as horizontal edges.


Input



      The first line of the input file contains n — the number of sticks (1 ≤ n ≤ 100). The second line contains n integer numbers — the lengths of the sticks he has. The length of each stick doesn’t exceed 200.


Output



      Print l — the number of sticks Johnny can use at the first line of the output file. The following 2l lines must contain the vertices of the rectangular polygon Johnny can construct. Vertices must be listed in order of traversal. The first two vertices must be the ends of a horizontal edge. If there are several solution, output any one. Vertex coordinates must not exceed 10  9
.      If no polygon can be constructed, output l = 0.


Sample Input



4 1 2 3 5 4 1 2 4 8 4 1 1 1 1


Sample Output



3 0 0 1 0 1 1 3 1 3 2 0 2 0 4 0 0 1 0 1 1 2 1 2 -2 1 -2 1 -1 0 -1


Hint



单组数据

      In the first example Johnny uses a stick of length 1 for (0, 0)−(1, 0) edge, a stick of length 2 for (1, 1)−(3, 1) edge and a stick of length 3 for (3, 2) − (0, 2) edge. There is no way to use all four sticks.


dp+记录路径

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 40005;
int f[105][maxn], p[105][maxn], a[maxn], l, r, n, b[2][maxn];

int main()
{
int i, j;
while (~scanf("%d", &n))
{
memset(f, 0, sizeof(f));
memset(p, 0, sizeof(p));
f[0][l = r = 20000] = 1;
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
for (j = l; j <= r; j++)
{
if (f[i][j]<f[i - 1][j])
{
f[i][j] = f[i - 1][j];
p[i][j] = p[i - 1][j];
}
if (f[i - 1][j])
{
if (f[i][j + a[i]]<f[i - 1][j] + 1)
{
f[i][j + a[i]] = f[i - 1][j] + 1;
p[i][j + a[i]] = -i;
}
if (f[i][j - a[i]]<f[i - 1][j] + 1)
{
f[i][j - a[i]] = f[i - 1][j] + 1;
p[i][j - a[i]] = i;
}
l = min(l, j - a[i]);
r = max(r, j + a[i]);
}
}
}
printf("%d\n", f[n][20000] - 1);
if (f[n][20000]>1)
{
int k1 = 0, k2 = 0;
for (i = p[n][20000], j = 20000; i;)
{
if (i>0)
{
b[1][k2++] = a[i];
j += a[i];
i = p[i - 1][j];
}
else
{
i = -i;
b[0][k1++] = a[i];
j -= a[i];
i = p[i - 1][j];
}
}
int x = 0, y = 0;
for (i = 0; i<k1; i++)
{
printf("%d %d\n", x, y);
printf("%d %d\n", (x += b[0][i]), y++);
}
for (i = 0; i<k2; i++)
{
printf("%d %d\n", x, y);
printf("%d %d\n", (x -= b[1][i]), y++);
}
}
}
return 0;
}



标签:use,polygon,Johnny,1429,sticks,int,Polygon,ACdream,must
From: https://blog.51cto.com/u_15870896/5837729

相关文章

  • Polygon Clipping using DotProduct
    写在前面:本文章为个人学习笔记,方便以后自己复习,也希望能帮助到他人。由于本人水平有限难免出现错误,还请评论区指出,多多指教。部分图元和素材来源于网络,如有侵权请联系本......
  • POJ 1389. Area of Simple Polygons 题解
    关于扫描线的介绍可以去看OIWiki。但那上面的参考代码并不好,下面给出了带注释的POJ1389题代码。/**Title:AreaofSimplePolygons*Source:POJ*URL:htt......
  • *Educational Codeforces Round 87 (Rated for Div. 2) C1. Simple Polygon Embedding
    https://codeforces.com/problemset/problem/1354/C1题目大意:给定一个数字n,表示构建出一个大小为2*n的边长的多边形;问我们可以装下这个多边形的最小的正方形的边长是......
  • P4342 [IOI1998]Polygon
    给定一个多边形,边上有符号,为\(+\)或\(\times\),点上有权值。先断掉一条边变成链,再在其他边上进行缩边,将两个点变为一个点,权值为两点做边上的运算。求最大值和最大值对应......
  • P1452/CF429D/P6247/P1429/P7883
    (P1452)给定\(n\)个点,求最远点对。\(n\leq5\times10^4\)。(CF429D)给定\(n\)个点,求最近点对。\(n\leq10^5\)。(P6247)给定\(n\)个点,求最近点对和最远点对。\(n\le......