2018 Multi-University Training Contest 1

11 篇文章 0 订阅

1001:Maximum Multiple
从n中拆出x,y,z,并要求x,y,z能被n整除且xyz最大。推一下就能够知道符合要求的时候就是能被三整除或者能被四整除时候,分为n/3,n/3,n/3或者n/4,n/4,n/2。

#include<bits/stdc++.h>
using namespace std;
int main(){

    long long n;
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%lld",&n);
        if(n%3!=0&&n%4!=0)
        cout<<"-1"<<endl;
        else  if(n%3==0)
        {
          long long a=n/3;
          long long ans=a*a*a;
          printf("%lld\n",ans);
        }
        else if(n%4==0)
        {
            long long a=n/2;
            long long b=n/4;
            long long ans=a*b*b;
            printf("%lld\n",ans);
        }
    }
    return 0;
}

1002:Balanced Sequence
首先从每个括号序列中求出能够匹配的括号,剩下的不能匹配的括号用结构体或者pair保存下来。然后就是把这些序列排序一下得到能匹配的最大结果,乘2输出即可。
重点在怎么排序:去掉能够匹配的括号之后的序列可以类似的看成)))(((这样的情况,在这种情况下,我们肯定要保证把)))))))))))))))))((这样的序列尽可能的放到后面,把))((((((((((((这样的序列尽可能的放到前面,这样才能够让组合起来的时候匹配括号数量最多。

#include<bits/stdc++.h>
using namespace std;
#define LL long long int
int T;
int n;
char c[100100];
struct node
{
    int a,b;
}s[100100];
stack<char>sta;
bool cmp(node x,node y)
{
    if(x.a>x.b&&y.a<=y.b)
        return 1;
    if(x.a<=x.b&&y.a>y.b)
        return 0;
    if(x.a>x.b&&y.a>y.b)
        return x.b<y.b;
    return x.a>y.a;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        LL res=0;
        for(int i=0;i<n;i++)
        {
            scanf("%s",c);
            for(int j=0;c[j];j++)
            {
                if(c[j]=='(')
                    sta.push(c[j]);
                if(c[j]==')')
                {
                    if(!sta.empty()&&sta.top()=='(')
                        sta.pop(),res++;
                    else
                        sta.push(c[j]);
                }
            }
            s[i].a=s[i].b=0;
            while(!sta.empty())
            {
                if(sta.top()=='(')
                    s[i].a++;
                else
                    s[i].b++;
                sta.pop();
            }
        }
        sort(s,s+n,cmp);
        int l=0,r=0;
        for(int i=0;i<n;i++)
        {
            res+=min(l,s[i].b);
            l-=min(l,s[i].b);
            l+=s[i].a;
        }
        printf("%lld\n",res<<1);
    }
    return 0;
}

1003:Triangle Partition
这道题目直接按x轴排一下序,然后输出就行了。

#include<bits/stdc++.h>
using namespace std;
struct node{
    long long a,b;
    int id;
}p[99999];
bool cp(node x,node y)
{
    if(x.a!=y.a)return x.a<y.a;
    return x.b<y.b;
}
int main(){

    long long n;
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%lld",&n);
        for(int i=1;i<=n*3;i++)
        scanf("%lld%lld",&p[i].a,&p[i].b),p[i].id=i;
        sort(p+1,p+1+3*n,cp);
        for(int i=1;i<=n*3;i+=3)
        printf("%d %d %d\n",p[i].id,p[i+1].id,p[i+2].id);

    }
    return 0;
}

1004:Distinct Values
贪心的写法,我们首先将要求的区间按照起始位置从左到右排序,然后用一个set维护当前可以使用的数。从左往右遍历不断地从set中取出数字使用。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
int T;
int n, m;
int res[100100];
struct node
{
    int l, r;
}s[100100];
bool cmp(node x, node y)
{
    if (x.l == y.l)
        return x.r > y.r;
    return x.l < y.l;
}
set<int>num;
int main()
{
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < m; i++)
            scanf("%d%d", &s[i].l, &s[i].r);
        sort(s, s + m, cmp);
        for (int i = 1; i <= n; i++) num.insert(i);
        int l = 1, r = 0;
        for (int i = 0; i < m; i++)
        {
            if (s[i].r <= r)
                continue;
            if (s[i].l > r)
            {
                while (r<s[i].l)
                    res[++r] = 1;
                while (l<s[i].l) num.insert(res[l++]);
                if ((*num.begin()) == 1) num.erase(num.begin());
            }
            else
            {
                while (l<s[i].l) num.insert(res[l++]);
            }
            while (r<s[i].r)
            {
                res[++r] = (*num.begin());
                num.erase(num.begin());
            }
        }
        while (r < n)
            res[++r] = 1;
        int p = 0;
        for (int i = 1; i <= n; i++)
        {
            if (p++) cout << " ";
            cout << res[i];
        }
        cout << endl;
    }
    return 0;
}

1011:Time Zone
输入一个北京时间,然后根据给定的时区求出时区时间。虽然用C的输入直接输入浮点数很简便,但是浮点数精度丢失会wa成狗。所以后面用了一个字符串处理的操作。(大佬有用浮点数处理的,先乘10变成整数然后乘6就行了,比赛当时没想到)

#include<bits/stdc++.h>
using namespace std;
#define LL long long int
int T;
int x,y;
char op[11];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d UTC%s",&x,&y,&op);
        int opp=0;
        int oppp=0;
        int flag;
        if(op[0]=='-') flag=-1;
        else flag=1;
        for(int i=1;op[i];i++)
        {
            if(op[i]>='0'&&op[i]<='9')
                opp=opp*10+op[i]-'0';
            if(op[i]=='.')
            {
                oppp=op[i+1]-'0';
                break;
            }
        }
        opp=opp*60+oppp*6;
        opp*=flag;
        opp-=480;
        y+=opp;
        while(y<0)
        {
            y+=60;x--;
        }
        while(y>59)
        {
            y-=60;x++;
        }
        y=(y+600)%60;
        x=(x+240)%24;
        printf("%02d:%02d\n",x,y);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值