【codeforces 733D】【贪心 乱搞】D. Kostya the Sculptor【给你n个长方形,让你找出2个或1个长方体,使得他们拼接成的长方体的内接圆半径最大】

来源:互联网 发布:大数据规划 编辑:程序博客网 时间:2024/05/21 16:58

传送门:http://codeforces.com/contest/733/problem/D

题意:给你n个长方形,让你找出2个或1个长方体,使得他们拼接成的长方体的内接圆半径最大(两个矩形拼接的条件是他们有一个面完全相同)


思路:

很容易想到一个长方体的内接圆半径是由他的最短的那条边决定的,

拼的时候贪心思想就是拼完之后让最小边变大,所以按两条边较长那个面把两个长方体拼起来

纯暴力复杂度是O(n^2)

设长方体的边长从大到小分别为a,b,c,

我们读入的时候将长方体边长排序

然后sort 以a为第一关键字 以b为第二关键字 以c为第三关键字

然后再进行拼接操作复杂度是O(n)


代码:

#include <bits/stdc++.h>using  namespace  std;#define ff first#define ss second#define rep(i,k,n) for(int i=k;i<=n;i++)typedef pair<pair<int, int>, pair<int, int> >piii;template<class T> void read(T&num) {    char CH; bool F=false;    for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());    for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());    F && (num=-num);}const int N=1e5+10;piii p[N];int n, a[3];int  main(){  read(n);  int ans = 0,pos1, pos2 = -1;  rep(i, 1, n){    rep(j, 0, 2)read(a[j]);    sort(a, a + 3);    p[i] = {{a[1], a[2]}, {a[0], i}};    if(ans < a[0])ans = a[0], pos1 = i;//不合并  }    sort(p + 1, p + n + 1);  rep(i, 1, n){    if(p[i].ff == p[i + 1].ff){//按较大的两条边合并      int x = p[i].ss.ff + p[i + 1].ss.ff;      x = min(x, p[i].ff.ff);      if(ans < x) ans = x, pos1 = p[i].ss.ss, pos2 = p[i + 1].ss.ss;    }  }  if(pos2 == -1){    printf("1\n%d\n", pos1);  }  else{    printf("2\n%d %d\n", pos1, pos2);  }  return 0;}
PS:巧用pair比手写结构体方便一些


当然当a,b相等时也可以用map找到c最大的两个三元组来更新答案,这样复杂度为O(nlogn)

代码:

(结构体写的,写的有些啰嗦)

#include <bits/stdc++.h>using  namespace  std;#define rep(i,k,n) for(int i=k;i<=n;i++)typedef pair<int, int> P;const int N=1e5+10;int a[N][3];std::map<P, int> mp;int n;struct node{  int  a[3];  int pos;  void st(){    sort(a, a+3);  }  bool operator < (const node& tmp)const{  if(tmp.a[1]==a[1]){    if(tmp.a[2]==a[2]){      return a[0]<tmp.a[0];    }    else return a[2]<tmp.a[2];    }  else return a[1]<tmp.a[1];  }}p[N];int  main(){  cin>>n;  rep(i, 1, n){    cin>>p[i].a[0]>>p[i].a[1]>>p[i].a[2];    p[i].pos = i;    p[i].st();  }  sort(p+1, p+n+1);/*  rep(i, 1, n){//输出    cout<<p[i].a[0]<<p[i].a[1]<<p[i].a[2]<<endl;  }*/  int mx=0, pos1;  rep(i, 1, n){//不合并    if(p[i].a[0]>mx)pos1=p[i].pos, mx = p[i].a[0];  }  rep(i, 1, n){//添加二元组    mp[make_pair(p[i].a[1], p[i].a[2])]++;    }  int pos21, pos22,i=1;  bool flag=false;  while(i<=n){//合并后    int sz=mp[make_pair(p[i].a[1], p[i].a[2])];    if(sz <=1)i++;    else{      i += sz;      int fg = min(p[i-1].a[1], p[i-2].a[0]+p[i-1].a[0]);      if(fg > mx){        flag=true;        mx=fg;        pos21=p[i-2].pos;        pos22=p[i-1].pos;      }    }  }  if(!flag){    puts("1");    printf("%d\n", pos1);  }  else{    puts("2");    printf("%d %d\n", pos21, pos22);  }  return 0;}





 





0 0
原创粉丝点击