• csp非零段划分


    202109-2 非零段划分

    计算机软件能力认证考试系统

    code:

    1. #include
    2. using namespace std;
    3. const int N=5e5+9;
    4. int a[N];
    5. vector<int> v[N];//v[i]存放所有元素值为i的元素的下标
    6. int main()
    7. {
    8. ios::sync_with_stdio(false);
    9. cin.tie(0),cout.tie(0);
    10. int n;cin>>n;
    11. for(int i=1;i<=n;++i)
    12. {
    13. cin>>a[i];
    14. v[a[i]].push_back(i);
    15. }
    16. //计算p=1的情况(即不修改)下的非零短
    17. int cnt=0;
    18. for(int i=1;i<=n;++i){
    19. if(a[i-1]==0&&a[i]!=0) cnt++;
    20. }
    21. int ans=cnt;
    22. //枚举p,因为1<=a[i] <= 1e4,所以p的有效范围并不大
    23. for(int p=2;p>=1e4+1;++p)
    24. {
    25. //这里只需要枚举v[p-1]即可,因为[1,p-2]的都已经被前面的给修改过了
    26. //计算p=1的情况(即不修改)下的非零段
    27. for(const auto &i : v[p-1])
    28. {
    29. a[i]=0;
    30. //我们考虑什么情况下会使得非零段变化
    31. //当修改这个位置,使得一个非零段"断开“,就会使得非零段数量+1
    32. if(a[i-1]!=0&&a[i+1]!=0) cnt++;
    33. //如果修改的位置是长度非1的非零段边缘的话,是不会改变非零段的数量的
    34. //当修改这个位置,使得一个长度为”1“的非零段消失,就会使得非零短-1
    35. if(a[i-1]==0 && a[i+1]==0) cnt--;
    36. }
    37. ans=max(ans,cnt);
    38. }
    39. }

    注:最开始写的二分 然后得了20分

    原因:不具有单调性

    随着p增大,这个非零段的数量可能变大也可能变小,甚至比赛先变大再变小之类的,就是不确定的

    计算机软件能力认证考试系统

    202303-2 垦田计划

    70分code:

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int N = 1e5+10;
    6. int n,m,k;
    7. typedef pair<int,int>PII;//采用pair同时存储t和c
    8. priority_queue > heap;//采用优先队列
    9. int main()
    10. {
    11. cin>>n>>m>>k;
    12. for(int i=1;i<=n;i++)
    13. {
    14. int t,c;
    15. cin>>t>>c;
    16. heap.push({t,c});//压入队列
    17. }
    18. while(m>0)
    19. {
    20. PII t = heap.top();//取出当前基础耗时最大的
    21. heap.pop();//记得删除最大点
    22. //如果最大值不满足条件
    23. if(t.first<=k)
    24. {
    25. heap.push(t);
    26. break;
    27. }
    28. m -=t.second;//每次只缩减一天
    29. t.first -= 1;
    30. heap.push(t);
    31. }
    32. cout<top().first<//输出基础耗时最大的值
    33. return 0;
    34. }

    100分code:

    1. #include
    2. using namespace std;
    3. const int N=5e5+9;
    4. typedef long long ll;
    5. ll n,m,k;
    6. ll c[N],t[N];
    7. bool check(ll mid){
    8. //检查天数mid是否可行
    9. ll sum=0;
    10. for(int i=1;i<=n;++i)
    11. {
    12. sum+=c[i]*max(0ll,t[i]-mid);
    13. }
    14. return sum<=m;
    15. }
    16. int main()
    17. {
    18. ios::sync_with_stdio(false);
    19. cin.tie(0),cout.tie(0);
    20. cin>>n>>m>>k;
    21. for(int i=1;i<=n;++i) cin>>t[i]>>c[i];
    22. //二分最小天数,答案可选范围是[k,inf]
    23. ll l=k-1,r=2e18;
    24. while(l+1!=r)//l
    25. {
    26. ll mid=(l+r)>>1;
    27. //如果mid可行,说明这个限制天数mid偏大,可以再变小,所以r=mid
    28. if(check(mid))r=mid;
    29. else l=mid;
    30. }
    31. cout<'\n';
    32. return 0;
    33. }

    特征:确定了最大天数的情况下可以O(n)计算代价

    并且代价越大,天数不会变大,所以具有单调性

    202212-2 训练计划

    1. #include
    2. using namespace std;
    3. const int N=5e5+9;
    4. typedef long long ll;
    5. //st[i]表示i项目的最早开始时间,ed[i]表示i项目的最晚开始时间
    6. int p[N],t[N],st[N],ed[N];
    7. //nex[i]存放i的所有后继
    8. vector<int> nex[N];
    9. int main()
    10. {
    11. ios::sync_with_stdio(false);
    12. cin.tie(0),cout.tie(0);
    13. int n,m;cin>>n>>m;
    14. for(int i=1;i<=m;++i)
    15. {
    16. cin>>p[i];
    17. //记录所有后继点
    18. nex[p[i]].push_back(i);
    19. }
    20. for(int i=1;i<=m;++i) cin>>t[i];
    21. bool ans=true;
    22. for(int i=1;i<=m;++i)
    23. {
    24. //如果有前驱,就是前驱的结束时间,否则就是从1开始
    25. st[i]=p[i]?st[p[i]]+t[p[i]]:1;
    26. //这里判断是否存在某个项目超出时间限制n
    27. if(st[i]+t[i]-1>n) ans=false;
    28. }
    29. for(int i=1;i<=m;++i) cout<" \n"[ i==m ];
    30. //如果不能在n天内完成,就直接结束
    31. if(!ans) return 0;
    32. //注意这里一定要倒这遍历,
    33. //这样才能保证nex[i]中的所有ed已经算出
    34. for(int i=m;i>=1;--i){
    35. ed[i]=n-t[i]+1;//初始化为最大(即没有后继的情况)
    36. //为了使得所有后继点的结束时间都在n以内,ed[i]应该取小
    37. }
    38. for(int i=1;i<=m;++i) cout<" \n"[i==m];
    39. return 0;
    40. }

    csp-

    试题编号:202012-2
    试题名称:

    期末预测之最佳阈值

    1. #include
    2. using namespace std;
    3. using ll = long long;
    4. vector<int> a, b, c;
    5. int main()
    6. {
    7. int n;cin >> n;
    8. for(int i = 1;i <= n; ++ i)
    9. {
    10. int y, res;cin >> y >> res;
    11. //分组存储
    12. if(res)a.push_back(y);
    13. else b.push_back(y);
    14. c.push_back(y);
    15. }
    16. sort(a.begin(), a.end());
    17. sort(b.begin(), b.end());
    18. sort(c.begin(), c.end());
    19. int ans = c[0], mx = 0;
    20. //c数组升序
    21. for(const auto &thr : c)
    22. {
    23. int sum = 0;
    24. //找出a中 >= thr 的数字的个数
    25. sum += a.size() - (lower_bound(a.begin(), a.end(), thr) - a.begin());
    26. //找出b中 < thr 的数字的个数
    27. sum += lower_bound(b.begin(), b.end(), thr) - b.begin();
    28. //当sum超过mx时,此时的thr肯定比之前的ans更好
    29. if(sum >= mx)ans = thr, mx = sum;
    30. }
    31. cout << ans << '\n';
    32. return 0;
    33. }

  • 相关阅读:
    【linux】[OOM]now anon-rss:0kB, file-rss:0kB, shmem-rss:280kB
    67个团建游戏
    Springboot基于Restful风格
    C++学习笔记二(堆栈、指针、命名空间、编译步骤)
    sql 限制返回的行数、从表中随机返回n行数据、将NULL转换为实际值
    【目标检测】雷达目标CFAR检测算法
    nginx负载均衡配置无效解决记录
    qt -- QTabWidget 中支持拖拽TabBar项
    spyder配置文件位置及使用说明
    HTTP协议加强
  • 原文地址:https://blog.csdn.net/heliotrope_jin/article/details/132699706