• D. Xenia and Colorful Gems(二分+暴力)


    Problem - 1337D - Codeforces

     题意:最近Xenia买了nr红色宝石,ng绿色宝石和nb蓝色宝石。每种宝石都有一个重量。假设所选宝石的重量为x、y和z,Xenia想找到(x-y)2+(y-z)2+(z-x)2的最小值。作为她亲爱的朋友,你能帮助她吗?

    题解:

    我们要找的钻石重量应该是符合这种规律的 a <= b<= c

    那我们就假设现在的是b,二分寻找a与c

    将三种宝石重量排序,r,g,b;

    1. void getmin(vecl r, vecl g, vecl b) {
    2. for (int i = 0; i < r.size(); i++) {
    3. ll x1 = upper_bound(g.begin(), g.end(), r[i]) - g.begin();
    4. ll x2 = lower_bound(b.begin(), b.end(), r[i]) - b.begin();
    5. if (x1 == 0 || x2 == b.size()) continue;
    6. x1--;
    7. ll x = r[i], y = g[x1], z = b[x2];
    8. Min = min(Min, pow2(x - y) + pow2(x - z) + pow2(y - z));
    9. }
    10. }
    11. getmin(r, g, b);
    12. getmin(r, b, g);
    13. getmin(b, r, g);
    14. getmin(b, g, r);
    15. getmin(g, r, b);
    16. getmin(g, b, r);

    大部分人写的核心代码,遍历a很好理解,为什么一个是lower_bound,一个是upper_bound

    因为a <= b<= c

    要找的是一个在左边,一个在右边,upper_bound后下标又减一代表找的是左边,找右边好说

    要换着再找一遍

    并且三个都要考虑,所以是六遍

    但是代码中这这一部分实在没搞明白

    所以我自己写了下面的

    1. if(x2 == c.size())
    2. {
    3. x2--;
    4. }
    5. if(x1 == b.size())
    6. {
    7. x1--;
    8. }
    9. else
    10. {
    11. if(x1!=0)
    12. x1--;
    13. }

    首先判断越界情况,如果有要减,其次x1就是upper_bound找左边的情况,如果没有一个是大于当前的,返回的下标是0,就不能减了;

     

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. #define int long long
    6. vector r,g,b;
    7. int mi = 9e18;
    8. int pow2(int x)
    9. {
    10. return x*x;
    11. }
    12. void solve(vectora,vectorb,vectorc)
    13. {
    14. for(int i = 0;i < a.size();i++)
    15. {
    16. int x1 = upper_bound(b.begin(),b.end(),a[i])-b.begin();
    17. int x2 = lower_bound(c.begin(),c.end(),a[i])-c.begin();
    18. if(x2 == c.size())
    19. {
    20. x2--;
    21. }
    22. if(x1 == b.size())
    23. {
    24. x1--;
    25. }
    26. else
    27. {
    28. if(x1!=0)
    29. x1--;
    30. }
    31. mi = min(mi,pow2(a[i]-b[x1])+pow2(a[i]-c[x2])+pow2(b[x1]-c[x2]));
    32. }
    33. }
    34. signed main()
    35. {
    36. int t;
    37. cin >> t;
    38. while(t--)
    39. {
    40. int nr,ng,nb;
    41. cin >> nr >>ng >> nb;
    42. r.clear();
    43. g.clear();
    44. b.clear();
    45. for(int i = 1;i <= nr;i++)
    46. {
    47. int x;
    48. cin >>x;
    49. r.push_back(x);
    50. }
    51. for(int i = 1;i <= ng;i++)
    52. {
    53. int x;
    54. cin >> x;
    55. g.push_back(x);
    56. }
    57. for(int i = 1;i <= nb;i++)
    58. {
    59. int x;
    60. cin >> x;
    61. b.push_back(x);
    62. }
    63. mi = 9e18;
    64. sort(r.begin(),r.end());
    65. sort(g.begin(),g.end());
    66. sort(b.begin(),b.end());
    67. solve(r,g,b);
    68. solve(r,b,g);
    69. solve(g,r,b);
    70. solve(g,b,r);
    71. solve(b,r,g);
    72. solve(b,g,r);
    73. cout<<mi<<"\n";
    74. }
    75. }

  • 相关阅读:
    解决MySQL需要根据特定顺序排序
    【Logback】开发环境怎么组织xml文件构建日志策略
    设计模式之门面模式
    Linux命令行如何设置MySQL远程连接
    关于技术面试思考
    TCP/IP五层协议栈(2)
    Java基础——反射
    90后小伙以这196道MySQL面试题,实力吊打面试官,生生挤进大厂
    40. 到达目的地的最短距离(第四期模拟笔试)
    elasticsearch14-高亮
  • 原文地址:https://blog.csdn.net/m0_64158084/article/details/127551144