HDU 2018 Multi-University Training Contest 1

1001 Maximum Multiple

题意:给出n,找x,y,z,n=x+y+z,x|n,y|n,z|n,求x*y*z的最大值

思路:因为整除关系,所以(x+y+z)/n=1/(n/x)+1/(n/y)+1/(n/z),得是1/2,1/3,1/4.。。。其中三个,分母是n因子,并且和为1.

然后写写,就三种情况,1/3+1/3+1/3,1/2+1/4+1/4,1/2+1/3+1/6,又因为有1/3 的情况一定是三个1/3最大。所以最后一种也是不可能选择,很简单

代码:

#include<bits/stdc++.h>
using namespace std;
long long n,m,a,b,c,t,ans;
int main()
{
    scanf("%lld",&n);
    while(n--)
    {
        scanf("%lld",&t);
        ans=-1;
        if(t%2==0&&t%3==0&&t%6==0)
        {
          ans=max(ans,t/2*t/3*t/6);
        }
        if(t%2==0&&t%4==0)
        {
            ans=max(ans,t/2*t/4*t/4);
        }
        if(t%3==0)
        {
            ans=max(ans,t/3*t/3*t/3);
        }
        printf("%lld\n",ans);
    }


    return 0;
}

1002   Balanced Sequence

题意:n个括号序列,随意连接成一个串,求匹配的括号的个数

思路:贪心,每个字符串预处理,留下左面的连续)和右面的连续(,中间已经匹配上的括号个数算出来,然后就是左面按照左面的)的多少排序,右面按照(的多少排序,然后匹配,因为这个题比赛的时候没A,不过想到了贪心思路,也知道是左右免得个数排序有关,但是没有明确思路,所以没有敲出来。然后赛后看直播时,大佬说如果实在想不出来,各种排序都试试,总一种是对的???真是涨姿势了!!(这个题还没有完全明白排序的由来,代码明天再补)

代码:

1003   Triangle Partition

题意:3*n个点,任意三点之间都不再一条直线上(任意三点都能组成一个三角形),求一种组合成n个三角形,任意三角形之间不相交。

思路:很水,给x和y排排序。然后一次输出,一行输出三个点的标号就可以了。。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxN=1e3+5;

struct Node{
    int x,y,id;
    bool operator < (const Node & obj)const
    {
        if(x!=obj.x) return x<obj.x;
        else return y<obj.y;
    }
}p[maxN*3];

int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=3*n;i++)
        {
            scanf("%d%d",&p[i].x,&p[i].y);
            p[i].id=i;
        }
        sort(p+1,p+3*n+1);
        for(int i=1;i<=3*n;i+=3)
        {
            printf("%d %d %d\n",p[i].id,p[i+1].id,p[i+2].id);
        }
    }
    return 0;
}

1004  Distinct Values

题意:n个点,m个区间,每个区间内的所有数不相同,给每个点赋值,求符合要求的最小字典序

思路:贪心,先按照区间左端点从小到大排序,右端点从大到小,然后去掉某些是其他区间的子区间的 区间,然后没有被区间覆盖的点,一定是放1,,,左端点开始的某部分若与前面的区间不重复,那么就说明,不受前面区间的影响,从1开始放,若重合一部分,那么重合的部分已排好,剩下的部分从前面没有的数中,从小的开始往里放,,

对于要往里放的数,可以用优先队列或者set存一下,没有放的数放在集合里,从左往右遍历,要放数的时候就从队列顶部出一个赋值,每个区间考虑完,要将与下一区间不重合的部分的数重新加入队列。这样只有2n的循环

代码:

(PS: 思路是自己的思路,但是比赛的时候因为set没用好,T了?最后是队友用同样思路敲的,A了。。。然后懒得敲了,直接上队友代码了。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#include <sstream>
#define inf 800000000
#define ll long long
#define mod 1000000007
using namespace std;
struct fuck
{
    int l,r,len;
}a[100010];
bool cmp(const fuck &x,const fuck &y)
{
    if(x.l==y.l)
        return x.len>y.len;
    return x.l<y.l;
}
struct cmp1
{
    bool operator ()(int &x,int &y)
    {
        return x>y;//最小值优先
    }
};
int res[100010];
int main()
{
    int T;
    scanf("%d",&T);//cin>>T;
    while(T--)
    {
        int n,m,i,cnt;
        priority_queue<int,vector<int>,cmp1>que;//最小值优先
        scanf("%d%d",&n,&m);
        for(i=0;i<m;i++)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].len=a[i].r-a[i].l+1;
        }
        for(i=1;i<=n;i++)
        {
            que.push(i);
        }
        sort(a,a+m,cmp);
        cnt=1;
        int cnt2=1;
        for(i=0;i<m;i++)
        {
            while(cnt<a[i].l)
            {
                res[cnt++]=1;
            }
            while(cnt2<a[i].l)
            {
                if(res[cnt2]==1&&que.top()==1)
                {
                    cnt2++;
                }
                else
                    que.push(res[cnt2++]);
            }
            while(cnt<=a[i].r)
            {
                res[cnt++]=que.top();
                que.pop();
            }
        }
        while(cnt<=n)
        {
            res[cnt++]=1;
        }
        printf("%d",res[1]);
        for(i=2;i<=n;i++)
        {
            printf(" %d",res[i]);//cout<<res[i]<<" ";
        }
        printf("\n");
    }
}

1007   Chiaki Sequence Revisited

题意:题目给出a【n】的表达式 了,求a[1]--a[n]的所有数的和

思路:可以算是规律题?打表能发现,a是单调不减序列,每个数出现的次数是lowbit(i)次,然后可以得出每个奇数出现一次,

2的k次方开始的等差为2的k次方的序列的每个数出现k+1次,然后二分就能求?,反正比赛的时候打表没发现这规律。。。看出一点苗头,却没有往lowbit上想,,,明天在补这个题。。

代码:

1011  Time Zone

题意:给出东八区的时间,求目标失去的时间。

思路:就是一个很复杂的大模拟,,很多细节,队友做的,,坐了很久,,终于A了,,算是恶心的签到题!

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#include <sstream>
#define inf 800000000
#define ll long long
#define mod 1000000007
using namespace std;
int geth (string s)
{
    int i,now=0;
    for(i=4;i<s.length();i++)
    {
        if(s[i]=='.')
        {
            break;
        }
        now=now*10+(s[i]-'0');
    }
    return now;
}
int getm (string s)
{
    int i,now=0;
    bool f=0;
    for(i=4;i<s.length();i++)
    {
        if(s[i]=='.')
        {
            f=1;
            continue;
        }
        if(f)
        {
            now=now*10+(s[i]-'0');
        }
    }
    now=now*6;
    return now;
}


int main()
{
    int n;
    scanf("%d",&n);//cin>>n;
    while(n--)
    {
        int h,m;
        char s[100];
        scanf("%d%d",&h,&m);//cin>>h>>m;
        scanf("%s",s);
        if(s[3]=='+')
        {
            m+=getm(s);
            if(m>=60)
            {
                h++;
                m%=60;
            }
            h+=geth(s);
            h-=8;
            if(h<0)
            {
                h+=24;
            }
            h%=24;

            if(h<10)
            {
                printf("0%d",h);//cout<<0<<h;
            }
            else
            {
                printf("%d",h);//cout<<h;
            }
            printf(":");//cout<<":";
            if(m<10)
            {
                printf("0%d",m);//cout<<0<<m;
            }
            else
            {
                printf("%d",m);//cout<<m;
            }
            printf("\n");//cout<<endl;
        }
        else
        {
            m-=getm(s);
            if(m<0)
            {
                h--;
                m+=60;
            }
            h-=geth(s);
            h-=8;
            if(h<0)
            {
                h+=24;
            }
            h%=24;

            if(h<10)
            {
                printf("0%d",h);//cout<<0<<h;
            }
            else
            {
                printf("%d",h);//cout<<h;
            }
            printf(":");//cout<<":";
            if(m<10)
            {
                printf("0%d",m);//cout<<0<<m;
            }
            else
            {
                printf("%d",m);//cout<<m;
            }
            printf("\n");//cout<<endl;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37868325/article/details/81174696