洛谷[USACO21DEC] Bracelet Crossings G
题目大意
小 B B B有 n n n条手链,编号为 1 1 1都 n n n,且第 i i i条手链的颜色为 i i i。这些手链满足以下三个条件:
- 每个手链是一个简单闭合折线,并且第一个点和最后一个点相同
- 没有手链与自身相交
- 没有两条手链相交
在手链摆好后,Farmer John开着拖拉机经过,桌子晃动起来,导致手链四处移动甚至可能断成了多个折线,小 B B B还是想检查以上三个条件是否仍然成立。然而,天色已暗,她现在无法看清手链。
但小 B B B有手电筒,她选择了 m m m条垂线 x = 1 , x = 2 , … , x = m x=1,x=2,\dots,x=m x=1,x=2,…,x=m,对于每条直线,她用手电筒从 y = − ∞ y=-\infty y=−∞扫到 y = + ∞ y=+\infty y=+∞,按照出现的顺序记录她看到的所有手链的颜色。没有光束穿过任何折线的顶点或同时穿过两条线段。对于每一束光,所有出现的颜色都恰好出现了两次。
求现在这 n n n条手链是否可能满足上面的三个条件。
有 t t t组数据。
1 ≤ t ≤ 50 , 1 ≤ n ≤ 50 , 1 ≤ m ≤ 50 1\leq t\leq 50,1\leq n\leq 50,1\leq m\leq 50 1≤t≤50,1≤n≤50,1≤m≤50
题解
首先,检查每个手链是不是连续的,不连续的话直接输出 N O NO NO。
再两两判断一下手链之间是否相交。对于手链 i i i和手链 j j j,我们可以判断手链是否有包含关系或相离关系。
包含比较好判断,直接看被包含的手链的颜色是否在包含的手链的颜色之间即可。
相离就不好直接判断了,我们可以分别判断。看 i i i是否完全在 j j j下面或 j j j是否完全在 i i i下面。如果 i i i和 j j j在 x x x轴的投影上有交集,则只要 i i i完全在 j j j下面或 j j j完全在 i i i下面,就是相离关系。如果 i i i和 j j j在 x x x轴的投影上没有交集,则显然不相交,这里也会判定其为相离。
如果既不是包含关系也不是相离关系,则就相交了。
总时间复杂度为 O ( ∑ n 2 m ) O(\sum n^2m) O(∑n2m)。
code
#include<bits/stdc++.h>
using namespace std;
int t,n,m,lt[105],rt[105],c1[105][105],c2[105][105];
bool baohan(int i,int j){
if(!(lt[i]<=lt[j]&&rt[i]>=rt[j])) return 0;
for(int o=lt[j];o<=rt[j];o++){
if(!(c1[o][i]<c1[o][j]&&c2[o][i]>c2[o][j])) return 0;
}
return 1;
}
bool xia(int i,int j){
for(int o=1;o<=m;o++){
if(c2[o][i]&&c1[o][j]&&c2[o][i]>c1[o][j]) return 0;
}
return 1;
}
bool pd(){
for(int i=1;i<=n;i++){
if(!lt[i]) continue;
for(int j=lt[i];j<=rt[i];j++){
if(!c1[j][i]) return 0;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
if(!baohan(i,j)&&!baohan(j,i)&&!xia(i,j)&&!xia(j,i)) return 0;
}
}
return 1;
}
int main()
{
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
memset(lt,0,sizeof(lt));
memset(rt,0,sizeof(rt));
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(int i=1,k;i<=m;i++){
scanf("%d",&k);
for(int j=1,x;j<=k;j++){
scanf("%d",&x);
if(!c1[i][x]) c1[i][x]=j;
else c2[i][x]=j;
if(!lt[x]) lt[x]=i;
rt[x]=i;
}
}
if(!pd()) printf("NO\n");
else printf("YES\n");
}
return 0;
}
文章描述了一个编程竞赛题目,涉及到的手链问题。题目要求检查在特定条件下,多条手链是否仍满足不自交、不相互交叉的条件。给定手电筒扫描的结果,需要判断手链的状态。解决方案包括检查手链连续性、判断手链间关系(包含、相离或相交),并提供了代码实现。

被折叠的 条评论
为什么被折叠?



