• 刷题记录(NC235267 星球大战,NC216012 Let‘s Play Curling,NC235294 任务,NC235569 牛可乐与NCPC)


    NC235267 星球大战

    题目链接

    关键点:

    1、用一个map来记每行(mx)的敌人(列数),再用一个map来记每列(my)的敌人(行数),map值为一个multiset因为数据可能重复。

    2、每当攻击一行时,对于消灭的人数即为记行的map的键值为d的size(mx[d].size()),然后遍历该mx[d],将所有的出现的列(比如为x)都在my中删除(my[x].erase(d)),然后再清除mx[d].clear()

    攻击一列也类似

    完整代码:

    1. # include
    2. # include
    3. # include
    4. # include
    5. using namespace std;
    6. int n, m;
    7. map<int, multiset<int>>mx;//记录某行上的战舰
    8. map<int, multiset<int>>my;;//记录某列上的战舰
    9. int main()
    10. {
    11. cin>>n>>m;
    12. for (int i=1; i<=n; i++)
    13. {
    14. int x, y;
    15. cin>>x>>y;
    16. mx[x].insert(y);
    17. my[y].insert(x);
    18. }
    19. for (int i=1; i<=m; i++)
    20. {
    21. int c, d, ans;
    22. cin>>c>>d;
    23. if (c==0)
    24. {
    25. ans = mx[d].size();
    26. multiset<int>::iterator it;
    27. for (it = mx[d].begin(); it!=mx[d].end(); it++)
    28. my[*it].erase(d);
    29. mx[d].clear();
    30. }
    31. else
    32. {
    33. ans = my[d].size();
    34. multiset<int>::iterator it;
    35. for (it = my[d].begin(); it!=my[d].end(); it++)
    36. mx[*it].erase(d);
    37. my[d].clear();
    38. }
    39. cout<
    40. }
    41. return 0;
    42. }

    NC216012 Let‘s Play Curling

    题目链接

    关键点:

    1、题目要求即为求连续红球的最多个数,可以通过多次画图得出

    2、用一个map来标记该球为红还是蓝,然后求红球的前缀和,如果红球中出现了篮球,那么当前前缀和直接清零,每次更新最大值

    完整代码

    1. # include
    2. using namespace std;
    3. int t;
    4. map<int, int>mp;
    5. map<int, int>cnt;
    6. int main()
    7. {
    8. cin>>t;
    9. while (t--)
    10. {
    11. int n, m;
    12. mp.clear();
    13. cnt.clear();
    14. cin>>n>>m;
    15. for (int i=1; i<=n; i++)
    16. {
    17. int x;
    18. cin>>x;
    19. mp[x] = 1;
    20. cnt[x]++;
    21. }
    22. for (int i=1; i<=m; i++)
    23. {
    24. int y;
    25. cin>>y;
    26. mp[y] = 2;
    27. cnt[y]=0;
    28. }
    29. int tmp = 0, ans = 0;
    30. for (auto &it : mp)
    31. {
    32. if (it.second == 2) tmp = 0;
    33. else tmp += cnt[it.first];
    34. ans = max(ans, tmp);
    35. }
    36. if (ans)
    37. cout<
    38. else
    39. cout<<"Impossible"<
    40. }
    41. return 0;
    42. }

    NC235294 任务

    题目链接

    关键点

    1、首先如何完成最多的任务,按时间为第一关键字,等级为第二关键字来从大到小排序,对于每一次的任务,我们找出可以完成的机器就去完成,不要管后面的任务(肯定也能完成),反正都是完成一次

    2、接下来为求最大的报酬

    (500∗xi​+2∗yi​)元报酬。
    xi(0

    yi​(0≤yi​≤10)

    因此就算对于 yi取最大也不如x相差1,因此按照该方式排序是有道理的

    3、接下来对于一个任务可能有多个机器都可以完成,那么我们就贪心的选择y刚刚好可以完成的机器

    4、因为y值可能相等,但又为不同的机器,因此我们可以用multiset来存对于该任务可以完成的机器,然后用lower_bound来求刚刚好可以完成ylevel的机器

    1. # include
    2. using namespace std;
    3. const int N = 100000+10;
    4. long long n, m, maxnum, maxpay;
    5. multiset<int>se;
    6. struct machine{
    7. int time;
    8. int level;
    9. }ma[N];
    10. struct task{
    11. int time;
    12. int level;
    13. }ta[N];
    14. bool cmp1(machine m1, machine m2)
    15. {
    16. if (m1.time!=m2.time)
    17. return m1.time>m2.time;
    18. else
    19. return m1.level>m2.level;
    20. }
    21. bool cmp2(task t1, task t2)
    22. {
    23. if (t1.time!=t2.time)
    24. return t1.time>t2.time;
    25. else
    26. return t1.level>t2.level;
    27. }
    28. int main()
    29. {
    30. cin>>n>>m;
    31. for (int i=1; i<=n; i++)
    32. {
    33. cin>>ma[i].time>>ma[i].level;
    34. }
    35. for (int i=1; i<=m; i++)
    36. {
    37. cin>>ta[i].time>>ta[i].level;
    38. }
    39. sort(ma+1, ma+1+n, cmp1);
    40. sort(ta+1, ta+1+m, cmp2);
    41. int pos = 1;
    42. for (int i=1; i<=m; i++)
    43. {
    44. while (pos<=n && ma[pos].time>=ta[i].time)
    45. {
    46. se.insert(ma[pos].level);
    47. pos++;
    48. }
    49. auto it = se.lower_bound(ta[i].level);
    50. if (it!=se.end())
    51. {
    52. maxnum++;
    53. maxpay = maxpay+500*ta[i].time+2*ta[i].level;
    54. se.erase(it);
    55. }
    56. }
    57. cout<" "<
    58. return 0;
    59. }

    NC235569 牛可乐与NCPC

    题目链接

    关键点:

    1、题目要求即为求每次肚子里没有点的点的个数

    2、因为点可能相同,但又为不同点,所以用一个multiset来存点(可以进入队伍的点),然后按照x,y从小到大排序,我们可以发现对于一个不能进入队伍的点,说明其有其他点在肚子里,以后无论再继续插入什么点,都无法改变其进入不了队伍的事实,因此每次判断下一个点时,只要判断其与进入队伍的点的关系就行

    3、对于每一次插入的点,我们先看该点是否能进入队伍,我们从multiset中lower_bound(),然后减一,找到比该点的x小的点,再看找到的点的y如果比该点大,那么该点就可以进入队伍(x,y从小到大排序)

    4、最后再清除因为该点加入而导致队伍里的其他点退出的点

    完整代码

    1. # include
    2. using namespace std;
    3. int t;
    4. struct ty{
    5. int x, y;
    6. bool operator < (const ty& a) const
    7. {
    8. if (x!=a.x)
    9. return x
    10. else
    11. return y
    12. }
    13. }p;
    14. multisetm;
    15. int main()
    16. {
    17. cin>>t;
    18. int cnt = 1;
    19. while (t--)
    20. {
    21. printf("Case #%d:\n", cnt++);
    22. int n;
    23. cin>>n;
    24. m.clear();
    25. for (int i=1; i<=n; i++)
    26. {
    27. int x, y;
    28. cin>>x>>y;
    29. p.x = x;
    30. p.y = y;
    31. auto it = m.lower_bound(p);
    32. if (it==m.begin() || (--it)->y>y)
    33. {
    34. m.insert(p);
    35. auto it = m.upper_bound(p);
    36. while (it!=m.end() && it->y>y)
    37. m.erase(it++);
    38. }
    39. cout<size()<
    40. }
    41. cout<
    42. }
    43. return 0;
    44. }

  • 相关阅读:
    大厂面试题-JVM为什么使用元空间替换了永久代?
    暑期JAVA学习(37)定时器
    【深度学习】 Python 和 NumPy 系列教程(廿六):Matplotlib详解:3、多子图和布局:subplots()函数
    3分钟开通GPT-4
    codemirror6教程
    运动用什么耳机不影响听力?运动骨传导耳机是最好的选择
    编译安装redis及配置多实例
    数字时代的自我呈现:探索个人形象打造的创新工具——FaceChain深度学习模型工具
    Yii2 关联查询结果AR对象 如何取到表以外的字段
    Flink自定义网课数据源
  • 原文地址:https://blog.csdn.net/m0_60531106/article/details/126168053