首页 > 其他分享 >SMU Summer 2023 Contest Round 3

SMU Summer 2023 Contest Round 3

时间:2023-07-13 20:02:03浏览次数:50  
标签:pre Summer Contest int SMU vector ans sum define

SMU Summer 2023 Contest Round 3

A. Curriculum Vitae

题意就是要求\(1\)后面不能有\(0\)的情况下的子序列最长长度, 也就是求一个最长不下降子序列,不过由于这是个\(01\)序列,也可以分别做一个前缀和求出\(0\)的数量,后缀和求\(1\)的数量,最后跑一遍循环,找一个最大值即可,

这里我是\(dp\)写的一个最长不下降子序列

#include  <bits/stdc++.h>
#define endl '\n'
#define int long long

using namespace std;

int n,m;
void solve(){
    cin >> n;
    vector<int> s(n);
    int one = 0;
    for(auto &i : s){
        cin >> i;
    }
    vector<int> dp(n);
    int ans = 0;
    for(int i = 0;i < n;i ++){
        dp[i] = 1;
        for(int j =0; j < i;j ++){
            if(s[i] >= s[j]){
                dp[i] = max(dp[j] + 1, dp[i]);
            }
        }
        ans = max(ans, dp[i]);
    }
    cout << ans << endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    int Ke_scholar = 1;
//    cin >> Ke_scholar;
    while(Ke_scholar--)
        solve();
    return 0;
}
/*
 */

B. Math Show

这题由于数据范围很小,可以直接暴力贪心求解

#include  <bits/stdc++.h>
#define endl '\n'
#define int long long
#define all(a) (a).begin(),(a).end()

using namespace std;

int n,m;
int match[N];
void solve(){
   int k,M;
   cin >> n >> k >> M;
   vector<int> a(k + 1);
   int sum = 0;
   for(int i = 1;i<= k;i++){
       cin >> a[i];
       sum += a[i];
   }
   sort(all(a));

   int ans = 0;
   for(int i = 0;i <= n;i ++){
       int score = i * k + i, t = sum * i, r = n - i;
       /*
       score 是完成i个人时的初始分数,因为完成一个人要+1,所以这里是直接+i;
       t是完成i个人所消耗的时间,当t大于M时就可以直接退出;
       r是目前为止还有几个人任务未完成.
       */
       if(t > M ) break;
       for(int j = 1;j <= k;j ++){
           if(t >= M) break;
           for(int p = 1;p <= r;p ++){
               t += a[j];
               if(t > M) break;
               score ++;
           }
       }
       ans = max(ans, score);
   }
   cout << ans << endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    int Ke_scholar = 1;
//    cin >> Ke_scholar;
    while(Ke_scholar--)
        solve();
    return 0;
}
/*
 */

C. Four Segments

题意翻译过来就在一个序列里找到\(i,j,k\)三个分界点使得\(sum(0, i) - sum(i, j) + sum(j, k) - sum(k, n)\)的值最大,\(sum( i,j)\)就是\(j\)的前缀和减去\(i\)的前缀和,如果直接暴力三层循环的话,时间肯定是不够的,这里我们可以发现这个公式前半部分\(sum(0,i) - sum(i,j)\)与它的的后半部分\(sum(j,k) - sum(k,n)\)在\(j\)是一个确定的值时其实是互不影响的,所以我们单独循环\(j\),然后分别去循环\(i\)和\(k\),找到两个部分的最大值时的\(i,k\)的值即可.

#include  <bits/stdc++.h>
#define endl '\n'
#define int long long
#define all(a) (a).begin(),(a).end()

using namespace std;

int n,m;
void solve(){
   cin >> n;
   vector<int> a(n + 1), pre(n + 1);
   for(int i = 1;i <= n;i ++){
       cin >> pre[i];
       pre[i] += pre[i - 1];
   }
   int ans = -LLONG_MAX;

   int ansi, ansk, ansj;
   for(int j = 0;j <= n;j ++){
      int sum1 = -inf, sum2 = -inf, sum;
      int si,sk;
      for(int i = 0;i <= j;i ++){
          if(pre[i] - (pre[j] - pre[i]) > sum1){
              sum1 =  pre[i] - (pre[j] - pre[i]);
              si = i;
          }
      }
      
      for(int k = j;k <= n;k ++){
          if(pre[k] - pre[j] - (pre[n] - pre[k]) > sum2){
              sum2 = pre[k] - pre[j] - (pre[n] - pre[k]);
              sk = k;
           }
       }
       
       sum = sum1 + sum2;
       if(sum > ans){
           ans = sum ;
           ansi = si, ansj = j, ansk = sk;
       }
   }
   cout << ansi << ' ' << ansj << ' ' << ansk << endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    int Ke_scholar = 1;
//    cin >> Ke_scholar;
    while(Ke_scholar--)
        solve();
    return 0;
}
/*
 */

D. Monitor

题意就是给出\(q\)个坏掉的像素点坐标和坏掉的时间,当这些点构成一个\(k*k\)的正方形时,说明显示屏会坏掉,而我们要找到它坏掉时的最小时间,如果\(q\)个坐标都不能构成这个正方形,则说明没坏,输出\(-1\).

做法是二分+二维前缀和,即先对每个坏掉的像素点坏掉的时间排序,然后去对这\(q\)个像素点二分,每次去检查它是否能构成一个\(k*k\)的正方形,不能就往后寻找,最后\(l > q\)的话则说明\(q\)个像素点都不能构成此正方形.

#include  <bits/stdc++.h>
#define endl '\n'
#define int long long
#define all(a) (a).begin(),(a).end()

using namespace std;

int n,m;
struct Node{
    int x,y,t;
};
vector<vector<int>> gg(501,vector<int> (501));
void solve(){
   int k , q;
   cin >> n >> m >> k >> q;
   vector<Node> a(q + 1);
   for(int i = 1;i <= q;i ++)
       cin >> a[i].x >> a[i].y >> a[i].t;

   sort(a.begin() + 1,a.end(),[](Node a, Node b){return a.t < b.t;});
   //这里如果你是从1开始输入的话,排序一定要从1开始排,因为它的t是可以等于0的

   auto check = [&](){
        for(int i = k;i <= n;i ++)
            for(int j = k; j <= m;j ++)
                if(gg[i][j] - gg[i - k][j] - gg[i][j - k] + gg[i - k][j - k] == k * k)
                    return true;
        return false;
   };

   int l = 1, r = q;
   while(l <= r){
       int mid = (l + r) >> 1;

       vector<vector<int>> g(n + 1, vector<int> (m + 1, 0));
       for(int i = 1;i <= mid;i ++)
           g[a[i].x][a[i].y] = 1;

       for(int i = 1;i <= n;i ++)
           for(int j = 1; j <= m;j ++)
               gg[i][j] = gg[i - 1][j] + gg[i][j - 1] - gg[i - 1][j - 1] + g[i][j];

       if(check())
           r = mid - 1;
       else
           l = mid + 1;
   }

   cout << (l > q ? -1 : a[l].t) << endl;

}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    int Ke_scholar = 1;
//    cin >> Ke_scholar;
    while(Ke_scholar--)
        solve();
    return 0;
}
/*
 */

标签:pre,Summer,Contest,int,SMU,vector,ans,sum,define
From: https://www.cnblogs.com/Kescholar/p/17551975.html

相关文章

  • 【DP】DMOPC '21 Contest 8 P5 - Tree Building
    ProblemLink给定\(n,m\)和一个长为\(m\)的代价序列,对于一棵\(n\)个节点,每个节点度数不超过\(m\)的树,定义它的代价为\(\sum\limits_{i=1}^na_{deg_i}\)。求代价最小的树的代价。\(n\le10^9,m\le3000,1\lea_i\le10^9\)。首先一眼变成选出\(n\)个\(a\)的和为......
  • AtCoder Beginner Contest 161
    AtCoderBeginnerContest161https://atcoder.jp/contests/abc161这套不算难,但是sb我还是写不出来是为什么呢F是个妙妙题C-ReplacingIntegerWA了一次所以放上来#include<bits/stdc++.h>#definelllonglongusingnamespacestd;intmain(){lla,b;c......
  • AtCoder Grand Contest 012 D Colorful Balls
    洛谷传送门AtCoder传送门不错的题。bxEnder32k。我们发现交换有传递性,那么我们能交换就连边,答案是\(\prod\frac{(sz)!}{\prodc_i!}\),其中\(sz\)为连通块大小,\(c_i\)为这个连通块中第\(i\)种颜色出现次数。于是我们得到了一个\(O(n^2)\)的做法。发现很多遍是无用的......
  • UESTC 2023 Summer Training #02 Div.2
    Preface都给我丑完了这怎么办啊,被血虐了苦路西这场本来前面感觉都还可以,但是当中期看了眼C的题意后准备开C后就不对劲了起来最后1h扔掉一直T的C题去做H,结果因为被卡自然溢出的Hash一直挂到比赛结束,直接红温感觉这场策略问题挺大的,比如没有跟榜去写更加简单的E题(比赛的时候题......
  • AtCoder Regular Contest 164 E Segment-Tree Optimization
    洛谷传送门AtCoder传送门妙妙题。我们考虑如何方便地描述一棵广义线段树。不难想到使用断点描述,即对于一个结点\([l,r]\),它的左右儿子分别是\([l,mid],[mid+1,r]\),其中\(mid\in[l,r-1]\),然后把一层缩成一个\(2^{d-1}\)的序列,每一层都是上层对应结点的\(mid......
  • AtCoder Beginner Contest 309 G Ban Permutation
    洛谷传送门AtCoder传送门前置知识:[ARC132C]AlmostSorted看\(\geX\)不顺眼,怎么办呢!直接容斥!钦定\(j\)个位置满足\(|P_i-i|<X\),其余任意,就转化成了[ARC132C]AlmostSorted。具体一点就是,你设\(f_{i,j,S}\)表示前\(i\)位有\(j\)个位置满足\(|P_i-i|<......
  • SMU Summer 2023 Contest Round 2
    SMUSummer2023ContestRound2A.TreasureHunt当\(x1-x2\)的差值与\(y1-y2\)的差值都能被\(x,y\)整除时,且商之和为2的倍数就一定可以到达#include<bits/stdc++.h>#defineendl'\n'#defineintlonglong#defineinf0x3f3f3f3fusingnamespacestd;constintN......
  • SMU 2023 Spring 题单 第二周 贪心
    Saruman'sArmy首先对序列排序,然后逐个考虑覆盖,如果要覆盖当前的点,则标记点越靠后越好,所有向后找\(R\),选择最靠后的标记,然后从标记点开始在向后找\(R\)也是被标记过的,直接跳过#include<cstdio>#include<algorithm>usingnamespacestd;intread(){intx=0,f=1......
  • [Leetcode Weekly Contest]351
    链接:LeetCode[Leetcode]6451.找出最大的可达成数字给你两个整数num和t。如果整数x可以在执行下述操作不超过t次的情况下变为与num相等,则称其为可达成数字:每次操作将x的值增加或减少1,同时可以选择将num的值增加或减少1。返回所有可达成数字中的最大值......
  • AtCoder Regular Contest 164 (A-C)
    A.TernaryDecomposition思维难度其实可以作为第二题思路先考虑最优情况下需要多少个数来组成(不够就No)在考虑全部为1的情况下是否可行(N<K这种情况不行)剩下的情况,考虑每次把高位的1向下挪变为3,所需的数字+2那么即三进制拆分后,在[min,max]范围内,且与最优情况差值为......