SMU Spring 2023 Trial Contest Round 1

发布时间 2023-03-22 21:15:44作者: Ke_scholar

A. Prepend and Append

用ans记录n的值,然后双指针从前后判断是否一个为0一个为1,是的话则ans-2,否则退出循环即可.

#include<bits/stdc++.h>

using namespace std;
int t,n;
char a[2010];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> t;
    while(t--)
    {
        cin >> n;
        cin >> a;
        int ans = n;
        for(int i=0,j=n-1;i<=n/2,j>=n/2;i++,j--)
        {
            if(a[i] == '0' && a[j] == '1' || a[i] == '1' && a[j] == '0')
                 ans -= 2;
            else
             break;
        } 
        cout << ans << '\n'; 
    }
    
    return 0;
} 

 

B. Distinct Split

数组s1记录子串a中出现的字符个数,数组s2记录子串b中出现的字符个数,然后将两个子串中出现的字符次数记录到数组s1中,遍历字符串,每次将si对应字符的数量从s1中减去1,然后数组s2中加1,即用i将字符串分成两个子串,然后枚举1-26个字母,取每次f(a) + f(b) 的最大值即可.

#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N = 2e5+10; 
int t,n;
string a;
int s1[N],s2[N];
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> t;
    while(t--)
    {
        int res = 0;
        memset(s1,0,sizeof(s1));
        memset(s2,0,sizeof(s2));
        cin >> n;
        cin >> a;
        for(int i = 0; i < n; i ++)
         s1[a[i] - 'a' ] ++ ;
        for(int i = 0; i < n; i++)
         {
             s1[a[i] - 'a'] --;
             s2[a[i] - 'a'] ++;
             int ss1,ss2;
             ss1 = ss2 = 0;
             for(int j = 0; j < 26; j++)
              {
                  if(s1[j]) ss1 ++;
                  if(s2[j]) ss2 ++;
              }
            res = max(res, ss1 + ss2);
         }
         cout << res << '\n';
        
    }
    return 0;
} 

 

C. Negatives and Positives

题意是给定一个长度为n的数组a,每次可以将相邻的两个数取相反数,即a[i] = - a[i]; a[i+1] = - a[i+1];

问数组和的最大值,共有t次询问.

 

即,每次我们可以找两个相邻的数,判断这两个数的和是否为负数,是的话就取相反数.

#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N = 2e5+10;
int n,t,a[N],ans;
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> t;
    while(t--)
    {
        ans = 0;
        cin >> n;
        for(int i=1;i<=n;i++)
        {
            cin >> a[i];
            ans += a[i];
        }
        sort(a+1,a+n+1);
        for(int i=1;i<n;i+=2)
        {
            if(a[i] + a[i+1] < 0)
             {
                 ans -= (a[i] * 2);//因为之前ans+的时候是加的负数,所以这里取反加回来要乘2 
                 ans -= (a[i+1] * 2);
             }
        }
        cout << ans << "\n";
    }
    return 0;
 } 

 

D. Range Update Point Query

 

 

 

E. Dima and Guards

题意:

有一个正整数 n 和 4 组正整数 a,b,c,d求是否有一组数据满足  x + y = n  , 其中x >= min(a, b), y >= min(c, d), .如果存在这样的x和y,则输出这一组的x 和 y 即(n - x),否则输出-1;

对于每一个 x 和 y,都保证要 min(a,b) <= x ; min(c,d) <= y, min(a,b) <= xmin(c,d) <= y。所以我们可以对 x 和 y 都取最小值,判断是否成立,如果成立,那么就输出当前的序号、最小的 x 和 nx,最后结束程序即可。不然就输出-1,应为这已经是最小值,两数相加的和只会更大,而不会变小。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a,b,c,d; 
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    for(int i=1;i<=4;i++)
     {
         cin >> a >> b >> c >> d;
         int x = min(a, b), y = min(c, d);
         if(x + y <= n)
         {
             cout << i << ' ' << x << ' ' << n - x << '\n';
             return 0;
         }
     }
     cout << -1 << '\n';
    return 0;
}

F. Dima and To-do List

 题意:

 emm可以理解为有n个任务,a_i

 

#include<bits/stdc++.h>
#define int long long
#define INF 0x3f3f3f3f
using namespace std;
const int N = 1e5+10;
int n,k,a[N]; 
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    scanf("%lld%lld",&n,&k); 
        for(int i=1;i<=n;i++)
         scanf("%lld",a+i);
        int ans , minn = INF , sum = 0;
        for(int i=1;i<=k;i++)
         {
             sum = 0;
             for(int j=i;j<=n;j+=k)
              sum += a[j];
             if(sum < minn)
             {
                 minn = sum ;
                 ans = i;
             }
         }
         printf("%lld\n",ans);
    return 0;
}

 

 

G. Dima and Salad

 

 

H. Dima and Trap Graph