给定n个长方体,可以任意旋转长方体,问是否存在两个长方体其中一个长方体的长宽高都大于另一个长方体
任意旋转一个长方体,也就是将其长宽高进行交换,若所给n个长方体中存在满足要求的两个长方体,则在通过选择使其长宽高升序后,同样满足条件,则可以先对所有长方体的长宽高都排为升序。
由于要判断两个长方体之间是否满足要求,要比较长宽高三个属性值,则可以先将所有元素按第一维的属性值大小来排序,这样就省去一维属性值的判断。然后从小到大,在考虑剩余两维属性的情况下进行判断。我们可以考虑维护一个已经遍历过元素的1~对应第二维属性值区间内的最小第三维属性值来帮助判断。
#include
#define x first
#define y second
#define C(i) str[0][i]!=str[1][i]
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N =2e5+10, INF=0x3f3f3f3f;
struct Node{
int a,b,c;
};
Node nodes[N];
bool cmp(Node &n1,Node &n2){
return n1.a<n2.a;
}
int tr[N];
int cnt;
int lowbit(int x){
return x&-x;
}
int query(int x){
int res=INF;
for(int i=x;i;i-=lowbit(i)){
res=min(tr[i],res);
}
return res;
}
void update(int k,int x){
for(int i=k;i<=cnt;i+=lowbit(i)){
tr[i]=min(tr[i],x);
}
}
void solve() {
int n;
cin >>n;
cnt=0;
set<int> st;///去重
unordered_map<int,int> mp;
for(int i=1;i<=n;i++){
int a[3];
scanf("%d %d %d",&a[0],&a[1],&a[2]);
sort(a,a+3);
nodes[i]={a[0],a[1],a[2]};
st.insert(a[1]);
}
///使一维属性值有序
sort(nodes+1,nodes+1+n,cmp);
for(auto v:st){//离散化二维属性值
mp[v]=++cnt;
}
memset(tr,INF,sizeof(tr));
for(int i=1;i<=n;i++){
int l=i;
///对于一维属性值相同的元素要一块查询
while(l<n&&nodes[l+1].a==nodes[l].a) l++;
for(int j=i;j<=l;j++){
if(query(mp[nodes[j].b]-1)<nodes[j].c){
puts("Yes");
return ;
}
}
for(int j=i;j<=l;j++){
update(mp[nodes[j].b],nodes[j].c);
}
i=l;
}
puts("No");
}
int main() {
int t = 1;
//cin >> t;
while (t--) solve();
return 0;
}
#include
#define x first
#define y second
#define C(i) str[0][i]!=str[1][i]
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N =2e5+10, INF=0x3f3f3f3f;
struct Node{
int a,b,c;
};
Node nodes[N];
bool cmp(Node &n1,Node &n2){
return n1.a<n2.a;
}
int cnt;
struct Seg{
int l,r;
int val;
}tr[N*4];
void pushup(int u){
tr[u].val=min(tr[u<<1].val,tr[u<<1|1].val);
}
void build(int u,int l,int r){
if(l==r) tr[u]={l,r,INF};
else {
tr[u]={l,r};
int mid=(l+r)>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
}
void modify(int u,int x,int d){
if(tr[u].l==x&&tr[u].r==x) tr[u].val=min(tr[u].val,d);
else {
int mid=tr[u].l+tr[u].r>>1;
if(x<=mid) modify(u<<1,x,d);
else modify(u<<1|1,x,d);
pushup(u);
}
}
int query(int u,int l,int r){
if(tr[u].l>=l&&tr[u].r<=r) return tr[u].val;
int mid=tr[u].l+tr[u].r>>1;
int res=INF;
if(l<=mid) res=query(u<<1,l,r);
if(r>mid) res=min(res,query(u<<1|1,l,r));
return res;
}
void solve() {
int n;
cin >>n;
cnt=0;
set<int> st;
unordered_map<int,int> mp;
for(int i=1;i<=n;i++){
int a[3];
scanf("%d %d %d",&a[0],&a[1],&a[2]);
sort(a,a+3);
nodes[i]={a[0],a[1],a[2]};
st.insert(a[1]);
}
sort(nodes+1,nodes+1+n,cmp);
for(auto v:st){
mp[v]=++cnt;
}
build(1,1,cnt);
for(int i=1;i<=n;i++){
int l=i;
while(l<n&&nodes[l+1].a==nodes[l].a) l++;
for(int j=i;j<=l;j++){
if(query(1,1,mp[nodes[j].b]-1)<nodes[j].c){
puts("Yes");
return ;
}
}
for(int j=i;j<=l;j++){
modify(1,mp[nodes[j].b],nodes[j].c);
}
i=l;
}
puts("No");
}
int main() {
int t = 1;
//cin >> t;
while (t--) solve();
return 0;
}