SDNU_ACM_ICPC_2024_Winter_Practice_1st 赛后

Allswy / 2024-02-20 / 原文

A:

题目

给出t个n,对每个n,令n=x+y+z,x|n,y|n,z|n,输出最大的xyz的值。

解法

打表 找规律

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        ll n;
        cin>>n;
        if(n>=3 && (n%3 == 0 || n%4 == 0 ))
        {
            if(n%3==0)
            {
                ll tmp = n/3;
                cout<<tmp*tmp*tmp<<'\n';
            }
            else
            {
                ll tmp = n/4;
                cout<<tmp * tmp * tmp * 2<<'\n'; 
            }
        }
        else 
        {
            cout<<-1<<'\n';
        }
    }
    return 0;
}

B

题目大意

左右括号刚好匹配的串成为平衡串,其中 1.空串 2.两个平衡串相接的串 3.左右同时分别加上左括号、右括号的串 也是平衡串,求一个串中最长平衡串的长度。

解法

所给出的串先按串中左右括号的数量排序,然后遍历整个串,寻找要求的最大值。

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
struct node
{
    int l,r,nu;
    bool operator < (const node& aa)const
    {
        if(l<=r&&aa.l>aa.r) return false;
        if(l>r&&aa.l<=aa.r) return true;
        if(r>=l&&aa.r>=aa.l) return l>aa.l;
        return r<aa.r;
    }
}strs[100010];
char str[100010];
int main()
{
    ios;
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
        {
           cin>>str;
           int len=strlen(str);
           int num1=0,num2=0,num=0;
           for(int j=0;j<len;j++)
           {
               if(str[j]=='(')
                    num1++;
               else 
               {
                    if(num1)
                    num++,num1--;
               else
                    num2++;
               }
            }
            strs[i].l=num1;
            strs[i].r=num2;
            strs[i].nu=num;
        }
        sort(strs,strs+n);
        ll ans=0;
        ll ln=0;
        for(int i=0;i<n;i++)
        {
           ans+=strs[i].nu;
           if(ln&&strs[i].r)
           {
               if(ln>strs[i].r)
               {
                   ans+=strs[i].r;
                   ln-=strs[i].r;
               }
               else ans+=ln,ln=0;
           }
           ln+=strs[i].l;
        }
        cout<<ans*2<<'\n';
    }
    return 0;
}

C

题目大意

给出3n个点,求可以构造出n个不重叠三角形的点的标号

解法

题目保证了任意三点不共线,只要按照每个点的x、y坐标排序,便必然不会出现重叠的部分,然后三个为一组,即可得到目标三角形。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100050;
struct node
{
    int x,y,pos;
};

node a[maxn];

bool cmp(node n,node m)
{
    if(n.x == m.x) return n.y < m.y;
    return n.x<m.x;
}

int main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i = 1;i<=3*n;i++)
        {
            cin>>a[i].x>>a[i].y;
            a[i].pos = i;
        }
        sort(a+1,a+n*3+1,cmp);
        for(int i = 1;i<=3*n;i+=3)
        {
            cout<<a[i].pos<<' '<<a[i+1].pos<<' '<<a[i+2].pos<<'\n';
        }
    }
    return 0;
}

J

题目大意:

解法

正反对伤害各自预处理一个前缀和数组,使用时查询即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100050;
typedef long long ll;
ll mp[maxn],pre[maxn],repre[maxn];

int main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int n,m;
    cin>>n>>m;
    mp[0]=0,mp[n+1]=0;
    for(int i = 1;i<=n;i++) cin>>mp[i];
    for(int i = 1;i<=n;i++)
    {
        if(mp[i]<mp[i-1]) pre[i] = mp[i-1]-mp[i];
        else pre[i]=0;
    }
    for(int i = 1;i<=n;i++) pre[i]+=pre[i-1];
    for(int i = n;i>0;i--)
    {
        if(mp[i]<mp[i+1]) repre[i] = mp[i+1] - mp[i];
        else repre[i] = 0;
    }
    for(int i = n;i>0;i--) repre[i] += repre[i+1];
    while(m--)
    {
        int s,e;
        cin>>s>>e;
        if(s<e) cout<<pre[e] - pre[s]<<'\n';
        else cout<<repre[e] - repre[s]<<'\n';
    }
    return 0;
}

K

题目大意

时区转化

解法

注意读入方式以及数据处理方式即可。
记得交C++,不然会tle到怀疑人生。

#include<iostream>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    int x,y;
    while(t-- && ~(scanf("%d %d ",&x,&y)) )
    {
        int num1,num2;
        double cha;
        scanf("UTC%lf",&cha);
        num1 =cha;
        cha *=10;
        num2 = (int)cha % 10;
        num1 = 8-num1;
        x-=num1;
        num2*=6;
        y+=num2;
        if(y>=60)
        {
            y%=60;
            x++;
        }
        else if(y<0)
        {
            y+=60;
            x--;
        }
        x+=24;
        x%=24;
        printf("%02d:%02d\n",x,y);
    }
    return 0;
}
----------