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
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,不过想到了贪心思路,也知道是左右免得个数排序有关,但是没有明确思路,所以没有敲出来。然后赛后看直播时,大佬说如果实在想不出来,各种排序都试试,总一种是对的???真是涨姿势了!!详见代码。

代码:

#include 
#include
using namespace std;
char S[500000];
struct node
{
    int l,r;
}data[500000];
int cmp(node a,node b)
{
    int x= min(a.l,b.r);
    int y = min(a.r,b.l);
    return x>y|(x==y&&a.l>b.l);//排序方式是对任意两个序列,组成新括号多 的靠左,相等时,左括号多的在左,避免右括号较多,前面的左括号不够导致形成的新括号不是最多的
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        scanf("%d",&n);
        long long ans = 0;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",S);
            int len = strlen(S);
            int tmp_l = 0,tmp_r = 0;
            for(int j=0;j0)
                    {
                        tmp_l--;
                        ans++;
                    }
                    else tmp_r++;
                }
            }
            //cout<

1003   Triangle Partition

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

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

代码:

#include 
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

1004  Distinct Values

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

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

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

代码:

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

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include 
#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.ly;//最小值优先
    }
};
int res[100010];
int main()
{
    int T;
    scanf("%d",&T);//cin>>T;
    while(T--)
    {
        int n,m,i,cnt;
        priority_queue,cmp1>que;//最小值优先
        scanf("%d%d",&n,&m);
        for(i=0;i

1007   Chiaki Sequence Revisited

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

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

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

(PS:标称还没看懂,但是看了另一位大佬的博客,写的挺好的)

https://blog.csdn.net/ACTerminate/article/details/81173935

代码:

1011  Time Zone

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

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

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include 
#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>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<

 

你可能感兴趣的:(数学,数据结构,思维,单调队列)