ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[cf1444D]Rectangular Polyline

2021-10-12 22:03:31  阅读:182  来源: 互联网

标签:排序 int sum Rectangular 极角 Polyline 有解 cf1444D 线段


由于两种线段要交替出现,有解的必要条件即为$h=v$(以下均记为$n$)

进一步的,再假设两种线段依次对应于向量$(a_{i},0)$和$(0,b_{i})$,根据题意要求向量长度为给定值且和为0,那么也即有$|a_{i}|=l_{i},|b_{i}|=p_{i}$且$\sum_{i=1}^{n}a_{i}=\sum_{i=1}^{n}b_{i}=0$

使用背包判定是否存在这样的$a_{i}$和$b_{i}$,若不存在即无解,若存在则再求出任意一组

(可以证明此时一定有解,以下即为构造)

若$a_{i}$中的负数少于$b_{i}$则将两者全部取相反数,再将两者分别从大到小排序(其实只需要保证正数在负数前),最后将$(a_{i},b_{i})$作为一个整体极角排序,并依次选择$(a_{1},0),(0,b_{1}),(a_{2},0),...,(b_{n},0)$即可

(代码实现上通过将两边分别合理排序使得其已经极角排序)

不难发现,以此法最终方案一定是形如下图的形式,即合法

 

 

时间复杂度为$o(\frac{nC^{2}}{\omega})$,可以通过

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 1005
 4 bitset<N*N>f[N];
 5 int t,n,m,a[N],b[N];
 6 int calc(int *a){
 7     int m=0;
 8     for(int i=1;i<=n;i++)m+=a[i];
 9     if (m&1)return 0;
10     m>>=1;
11     for(int i=1;i<=n;i++)f[i]=((f[i-1])|(f[i-1]<<a[i]));
12     if (!f[n][m])return 0;
13     for(int i=n;i;i--)
14         if (!f[i-1][m]){
15             m-=a[i];
16             a[i]=-a[i];
17         }
18     return 1;
19 }
20 int main(){
21     f[0][0]=1;
22     scanf("%d",&t);
23     while (t--){
24         scanf("%d",&n);
25         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
26         scanf("%d",&m);
27         for(int i=1;i<=m;i++)scanf("%d",&b[i]);
28         if ((n!=m)||(!calc(a))||(!calc(b))){
29             printf("No\n");
30             continue;
31         }
32         int cnt=0;
33         for(int i=1;i<=n;i++)cnt+=(a[i]<0)-(b[i]<0);
34         if (cnt<0){
35             for(int i=1;i<=n;i++)a[i]=-a[i],b[i]=-b[i];
36         }
37         sort(a+1,a+n+1),reverse(a+1,a+n+1);
38         sort(b+1,b+n+1),reverse(b+1,b+n+1);
39         for(int i=1;i<=n+1;i++)
40             if ((i>n)||(a[i]<0)){
41                 reverse(b+1,b+i);
42                 break;
43             }
44         for(int i=n;i>=0;i--)
45             if ((!i)||(b[i]>0)){
46                 reverse(a+i+1,a+n+1);
47                 break;
48             }
49         printf("Yes\n");
50         for(int i=1,x=0,y=0;i<=n;i++){
51             x+=a[i],printf("%d %d\n",x,y);
52             y+=b[i],printf("%d %d\n",x,y);
53         }
54     }
55     return 0;
56 } 
View Code

 

标签:排序,int,sum,Rectangular,极角,Polyline,有解,cf1444D,线段
来源: https://www.cnblogs.com/PYWBKTDA/p/15399758.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有