ACdream 1429 Rectangular Polygon
Rectangular Polygon
Time Limit: 1000MS | Memory Limit: 256000KB | 64bit IO Format: %lld & %llu |
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.
Now 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.
Source
Andrew Stankevich Contest 23
第一问:求最多使用木棍数量。竖边可以无视,问题简化成从所有木棍中挑出一部分,分成总长度相等的两组,求最大总长度。动规可解。
第二问:具体摆法。由于是多解任意输出一解,竖边依旧可以无视。在之前的动规中保存一下每次用的木棍长度(我保存的是端点间相对位置),最后输出就行。
#include<algorithm> #include<cstdio> #include<cstring> #include<iostream> using namespace std; const int q=1000000007; const int mxn=120; const int bas=20400; int le,ri; int a[mxn]; int dp[mxn][bas*2],p[mxn][bas*2]; int n; int st1[mxn],tp1; int st2[mxn],tp2; int main(){ while(scanf("%d",&n)!=EOF){ memset(dp,-1,sizeof(dp)); memset(p,0,sizeof(p)); int i,j; le=ri=bas; for(i=1;i<=n;i++)scanf("%d",&a[i]); dp[0][bas]=0; p[1][bas]=bas; for(i=1;i<=n;i++){ for(j=le;j<=ri;j++){//枚举长度差 if(dp[i-1][j]<=-1)continue; if(dp[i][j]<dp[i-1][j]){ dp[i][j]=dp[i-1][j];//不选 p[i][j]=j; } if(dp[i][j+a[i]]<dp[i-1][j]+1)//放在上面 { dp[i][j+a[i]]=dp[i-1][j]+1; p[i][j+a[i]]=j; } if(dp[i][j-a[i]]<dp[i-1][j]+1)//放在下面 { dp[i][j-a[i]]=dp[i-1][j]+1; p[i][j-a[i]]=j; } } le-=a[i];//扩展规划范围 ri+=a[i]; } printf("%d\n",dp [bas]);//回答第一问:最多使用木棍数量 int tnow=bas;//最终端点位置 int tmp; tp1=0;tp2=0; for(i=n;i>=1;i--){//倒着找 tmp=p[i][tnow];//上次木棍端点位置 // printf("test: %d %d\n",tmp,tnow); if(tmp>tnow)st2[++tp2]=tmp-tnow; if(tmp<tnow)st1[++tp1]=tnow-tmp; tnow=tmp;//更新位置 } int x=0,y=0; while(tp2) { y++; printf("%d %d\n",x,y); x+=st2[tp2]; printf("%d %d\n",x,y); tp2--; } while(tp1) { y++; printf("%d %d\n",x,y); x-=st1[tp1]; printf("%d %d\n",x,y); tp1--; } } return 0; }
- angularjs中关于checkbox的问题
- 《AngularJs实战》笔记
- AngularJS 避繁就简的路由
- AngularJS使用指令增强标准表单元素功能
- AngularJS内建服务$location及其功能详解
- 学习Angularjs分页指令
- angularjs 获取当前时间并转化为字符串
- 仿Angular Bootstrap TimePicker创建分钟数-秒数的输入控件
- angularJS常用的表单验证指令
- AngularJS优雅的自定义指令
- Angularjs总结(一)表单验证
- Angular directive 实例详解
- angular 深入浅出
- angularjs1.0使用总结
- angularJS $resource与后台restapi的对应关系
- js、Jquery、AngularJs中的extend方法
- 一招制敌 - 玩转 AngularJS 指令的 Scope (作用域)
- AngularJS 常见面试问题
- AngularJS入门心得——directive和controller如何通信(推荐阅读)
- AngularJs(五)指令