码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #452 (Div. 2)

时间:2017-12-17 22:17:00      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:两种   void   暴力   scan   ret   har   while   元素   mes   

A. Splitting in Teams

水题贪心,数列有1,2两种元素,求组成3的最大方案,首先找到1的个数a,2的个数b,尽可能满足2,若b>=a,则就输出a,否则,输出b+(a-b)/3

代码如下:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

int main()
{
    int n;
    int a=0,b=0,x;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x);
        if(x==1)
            a++;
        else
            b++;
    }
    if(a<=b)
        printf("%d\n",a);
    else
        printf("%d\n",b+(a-b)/3);
    return 0;
}

 

B. Months and Years

暴力,特别注意:相邻两年不可能都是润年,因为数据量很小可以直接暴力

优化思路:看见大佬将三年的每月的天数转化成字符,(28 or 29 ---> ‘a‘, 30 ---->‘b‘,31---->‘c‘) 先进行特判,然后跑一边kmp

代码如下:

 

#include <iostream>
#include <stdio.h>
using namespace std;

int month[]={31,28,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31};
int main()
{
    int n;
    int a[25],b=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]/10==2&&a[i]%10==9)
            b++;
    }
    if(b>=2)
    {
        puts("NO");
        return 0;
    }
    int flag=0;
    for(int j=0;j<3*12;j++)
    {
        int o=j,i;
        for(i=0;i<n&&o<3*12;i++)
        {
            if(month[o]==a[i]||(month[o]/10==a[i]/10&&a[i]/10==2))
                o++;
            else
                break;
        }
        if(i==n)
        {
            puts("YES");
            return 0;
        }
    }
    puts("NO");
    return 0;
}

 

 

代码如下:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

int next[37];
void get_next(int next[],char s[],int len)
{
    int i=0,j=-1;
    j=next[0]=-1;
    while(i<len)
    {
        if(j==-1||s[i]==s[j])
        {
            i++,j++;
            next[i]=j;
        }
        else
            j=next[j];
    }
}
int kmp(char s[],char t[],int ls,int lt)
{
    int i=0,j=0;
    while(i<ls)
    {
        if(j==-1 || s[i]==t[j])
            i++,j++;
        else
            j=next[j];
        if(j>=lt)
            return 1;
    }
    return 0;
}
int main()
{
    int n,b=0,x,k=0;
    char str[]="cacbcbccbcbccacbcbccbcbccacbcbccbcbc",st[36];
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&x);
        if(x==29)
            b++;
        if(x/10==2)
            st[k++]=a;
        else if(x==30)
            st[k++]=b;
        else
            st[k++]=c;
    }
    st[k]=\0;
    if(b>=2)
    {
        puts("NO");
        return 0;
    }
    get_next(next,st,strlen(st));
    if(kmp(str,st,strlen(str),strlen(st)))
        puts("YES");
    else
        puts("NO");
    return 0;
}

 

C. Dividing the numbers

利用等差数列的一个性质:从等差数列的定义、通项公式,前n项和公式还可推出:a(1)+a(n)=a(2)+a(n-1)=a(3)+a(n-2)=…=a(k)+a(n-k+1),(类似:p(1)+p(n)=p(2)+p(n-1)=p(3)+p(n-2)=。。。=p(k)+p(n-k+1)),k∈{1,2,…,n}。

然后,找到规律:若该数n是4的倍数,相差最小为0,选出最前面和最后面的数个n/4个,若是2的倍数,相差最小为1,与选4类似,但最后的数只选后n/4-1个元素,若该数n为奇数,将1拿出来,判断(该数-1)是否是4 ,2 的倍数,与前偶数的类似

 

代码如下:

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int n;
    scanf("%d",&n);
    if(n%4==0)
    {
        printf("0\n%d ",n/2);
        for(int i=1;i<=n/4;i++)
        {
            if(i==n/4)
                printf("%d %d\n",i,n-i+1);
            else
                printf("%d %d ",i,n-i+1);
        }
        return 0;
    }
    if(n%2==0)
    {
        printf("1\n%d ",n/2);
        for(int i=1;i<=n/2;i+=2)
        {
            if(i==n/2)
                printf("%d\n",i);
            else
                printf("%d %d ",i,n-i+1);
        }
    }
    else
    {
        if((n-1)%4==0)
        {
            printf("1\n%d 1 ",n/2+1);
            for(int i=1;i<=(n-1)/4;i++)
            {
                if(i==(n-1)/4)
                    printf("%d %d\n",i+1,n-i+1);
                else
                    printf("%d %d ",i+1,n-i+1);
            }
        }
        else if((n-1)%2==0)
        {
            printf("0\n%d 1 ",n/2+1);
            for(int i=2;i<=n/2+1;i=i+2)
            {
                if(i==n/2+1)
                    printf("%d\n",i);
                else
                    printf("%d %d ",i,n-i+2);
            }
        }
    }
    return 0;
}

 

Codeforces Round #452 (Div. 2)

标签:两种   void   暴力   scan   ret   har   while   元素   mes   

原文地址:http://www.cnblogs.com/lemon-jade/p/8053273.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!