• F. Quests(二分)


    Problem - F - Codeforces

     

    有n个任务。如果你完成第i个任务,你将获得ai币。你每天最多只能完成一个任务。然而,一旦你完成了一个任务,在K天内你不能再做同样的任务。(例如,如果k=2,你在第1天做了任务1,那么你在第2天或第3天不能做,但你可以在第4天再做)。

    给你两个整数c和d。找出k的最大值,使你在d天内至少能获得c个硬币。如果不存在这样的k,则输出Impossible。如果k可以是任意大的,则输出Infinity

    输入
    输入由多个测试案例组成。第一行包含一个整数t(1≤t≤104)--测试案例的数量。测试用例的描述如下。

    每个测试用例的第一行包含三个整数n,c,d(2≤n≤2⋅105;1≤c≤1016;1≤d≤2⋅105)--任务的数量,你需要的硬币数量,以及天数。

    每个测试案例的第二行包含n个整数a1,a2,...,an(1≤ai≤109)--任务的奖励。

    所有测试案例的n之和不超过2⋅105,所有测试案例的d之和不超过2⋅105。

    输出
    对于每个测试用例,输出以下结果之一。

    如果不存在这样的k,输出Impossible。
    如果k可以是任意大的,则输出Infinity。
    否则,输出一个整数--k的最大值,使你在d天内至少能获得c个硬币。
    请注意,检查器是区分大小写的,你应该完全按照给出的字符串来输出。
    例子
    inputCopy
    6
    2 5 4
    1 2
    2 20 10
    100 10
    3 100 3
    7 2 6
    4 20 3
    4 5 6 7
    4 100000000000 2022
    8217734 927368 26389746 627896974
    2 20 4
    5 1
    输出拷贝
    2
    杅眕
    不可能的
    1
    12
    0
    备注
    在第一个测试案例中,在k=2的情况下,在4天内赚取5个金币的方法如下。

    第1天:做任务2,赚取2个金币。
    第二天:做任务1,赚取1个金币。
    第三天:什么都不做。
    第四天:做任务2,赚取2个硬币。
    总的来说,我们赚了2+1+2=5个硬币。
    在第二个测试案例中,我们可以通过做第一个任务赚取100个硬币,在第一天本身就可以赚取超过20个硬币,所以k的值可以任意大,因为我们从来不需要做另一个任务。

    在第三个测试案例中,无论我们怎么做,我们都无法在3天内赚到100个硬币。

    题解:
    首先我们把无限,与不可能的情况去除,

    什么时候无限,就是,min(d,n)个前最大的相加>=c,不需要重复加最大的都可完成,

    不可能则是每天都是最大的*d都无法达到c,就是不可能

    然后就是二分k的最大值,因为根据k的大小,钱数的大小肯定也是单调的

    关键是check函数怎么写,

    这里看了一下大佬的,觉得写的很简洁,很不错

    1. #include<iostream>
    2. #include<algorithm>
    3. #include<cstring>
    4. #include<string>
    5. #include<map>
    6. #include<vector>
    7. #include<queue>
    8. using namespace std;
    9. #define int long long
    10. int a[200050];
    11. void solve()
    12. {
    13. long long n,c,d;
    14. cin >> n >> c>>d;
    15. for(int i = 1;i <= n;i++)
    16. {
    17. cin >> a[i];
    18. }
    19. sort(a+1,a+1+n,greater<int>());
    20. long long s = 0;
    21. for(int i = 1;i <= min(n,d);i++)
    22. s+= a[i];
    23. if(s >= c)
    24. {
    25. cout<<"Infinity\n";
    26. return ;
    27. }
    28. if(a[1]*d < c)
    29. {
    30. cout<<"Impossible\n";
    31. return ;
    32. }
    33. int l = 0,r = 2e5;
    34. while(l < r)
    35. {
    36. int mid = (l + r+1)/2;
    37. s = 0;
    38. for(int i = 1;i <= d;i++)
    39. {
    40. int id = ((i-1) % (mid+1)+1);
    41. if(id <= n)
    42. {
    43. s += a[id];
    44. }
    45. }
    46. if(s >= c)
    47. {
    48. l = mid;
    49. }
    50. else
    51. {
    52. r = mid-1;
    53. }
    54. }
    55. cout<<l<<"\n";
    56. }
    57. signed main()
    58. {
    59. int t = 1;
    60. cin >> t;
    61. while(t--)
    62. {
    63. solve();
    64. }
    65. }

  • 相关阅读:
    华新集团再冲刺港交所上市:上半年收入2.6亿元,张德红为董事长
    android —— 阴影效果和跑马灯效果Textview
    导外库失败显示错误:Failed to resolve
    软件测试的前景怎么样?自学软件测试要怎么学?
    Spring 对 Java EE API 整合-5
    如何减小pdf文件的大小
    Linux中Too many open files
    mitmproxy 使用
    多线程中守护线程的使用
    Excel公式:使首字母小写--某列单元格首字母小写
  • 原文地址:https://blog.csdn.net/m0_64158084/article/details/127980656