现在的位置: 首页 > 综合 > 正文

Codeforces Round #142 (Div. 2)

2018年01月14日 ⁄ 综合 ⁄ 共 2258字 ⁄ 字号 评论关闭

第一题:Dragons

题意:一个有s点强壮值的战士,他要面对n条龙,龙有两个属性,x:只有当战士的强壮值大于x的时候才能打败这条龙,y:打败这条龙之后战士的强壮值可以增加y。龙的挑战顺序可以改变,问能否打败所有的龙。

题解:贪心。把龙按x的值从小到大排序,之后尝试累加即可。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
    int x,y;
}num[1005];
bool cmp(const struct node &a,const struct node &b)
{
    return a.x<b.x;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;++i)
        scanf("%d%d",&num[i].x,&num[i].y);
    sort(num,num+m,cmp);
    bool flag=false;
    for(int i=0;i<m;++i)
    {
        if(n>num[i].x)
            n+=num[i].y;
        else
        {
            flag=true;
            break;
        }
    }
    if(flag) puts("NO");
    else     puts("YES");
    return 0;
}

第二题:T-primes

题意:给你n个数字xi(1<=xi<=10^12),对于每个数字问它是否只有3个不同的因子。

题解:对于每个数xi,它必存在1和它本身两个不同的因子,可以得出第3个因子必是素数且它的平方等于xi。我们可以先打一张素数表,求得10^6以内的素数有哪些,再二分查找是否存在这样的素数。(枚举查找会超时的T^T)

代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define LL long long
LL prime[100000];
bool flag[1000005];
int idx;
void init()
{
    int i,j;
    idx=0;
    memset(flag,false,sizeof(flag));
    for(i=2; i<=1000000; ++i)
    {
        if(!flag[i])
        {
            prime[idx++]=i;
            for(j=i+i; j<=1000000; j=j+i)
                flag[j]=true;
        }
    }
}
int main()
{
    int n;
    LL num;
    init();
    scanf("%d",&n);
    for(; n--;)
    {
        bool ans=false;
        scanf("%I64d",&num);
        int l=0,r=idx-1,mid;
        for(;l<=r;)
        {
            mid=(l+r)>>1;
            if(prime[mid]*prime[mid]==num)
            {
                ans=true;
                break;
            }
            else if(prime[mid]*prime[mid]<num) l=mid+1;
            else                               r=mid-1;
        }
        if(ans) puts("YES");
        else    puts("NO");
    }
    return 0;
}

第三题:Shifts

题意:一个n*m的01矩阵,对于每行可以进行循环左移或者循环右移操作,问最小需要几次操作可以使得01矩阵中存在全由1组成列。

题解:对于每行中的每个点,计算出由这行中最近1转移过来的步数,之后对于每列统计步数和,取最小值。

代码:

#include<cstdio>
#include<cstring>
using namespace std;
int mapt[105][10005];
int num[105][10005];
int main()
{
    int n,m,idx,st;
    bool flagt=false;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;++i)
    {
        bool flag=true;
        getchar();
        for(int j=0;j<m;++j)
        {
            mapt[i][j]=(getchar()=='1'?1:0);
            if(mapt[i][j]==1) flag=false;
        }
        if(flag) flagt=true;
    }
    if(flagt) puts("-1");
    else
    {
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<m;++j)
                if(mapt[i][j]==1)
                {
                    st=j;
                    idx=j;
                    break;
                }
            num[i][st]=0;
            for(int j=(st+1)%m;j!=st;j=(j+1)%m)
                if(mapt[i][j]==1)
                {
                    num[i][j]=0;
                    idx=j;
                }
                else
                    num[i][j]=(j-idx+m)%m;
            idx=st;
            for(int j=(st-1+m)%m;j!=st;j=(j-1+m)%m)
                if(mapt[i][j]==1)
                {
                    num[i][j]=0;
                    idx=j;
                }
                else if(num[i][j]>(idx-j+m)%m)
                    num[i][j]=(idx-j+m)%m;
        }
        int maxx=(1<<30)-1,summ=0;
        for(int j=0;j<m;++j)
        {
            summ=0;
            for(int i=0;i<n;++i)
               summ+=num[i][j];
            if(summ<maxx) maxx=summ;
        }
        printf("%d\n",maxx);
    }
    return 0;
}

第四题:

题意:

题解:

代码:

第五题:

题意:

题解:

代码:

来源:http://blog.csdn.net/acm_ted/article/details/8036467

抱歉!评论已关闭.