NYIST-2019省赛训练个人积分赛第三场

A - 水题A

CodeForces - 106B

题意

电脑一共有三个属性和价格,如果一个电脑的三个属性都严格的小于其他的其中一个电脑,则这个电脑是过时,在不过时的电脑中选择价格最低的那个。。。
直接for循环遍历模拟

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
    int a,b,c,d,id;
};
node a[105],b[105];
int tot;
int cmp(node x,node y)
{
    return x.d<y.d;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d %d %d %d",&a[i].a,&a[i].b,&a[i].c,&a[i].d);
        a[i].id=i;
    }
    int flag=0;
    for(int i=1; i<=n; i++)
    {
        int flag=0;
        for(int j=1; j<=n; j++)
        {
            if(i!=j)
            {
                if(a[i].a<a[j].a&&a[i].b<a[j].b&&a[i].c<a[j].c)
                {
                    flag=1;
                    break;
                }
            }
        }
        if(!flag)
        {
            b[tot].a=a[i].a;
            b[tot].b=a[i].b;
            b[tot].c=a[i].c;
            b[tot].d=a[i].d;
            b[tot++].id=a[i].id;
        }
    }
    sort(b,b+tot,cmp);
    printf("%d\n",b[0].id);
    return 0;
}

·
·

B - 水题B

CodeForces - 203B

题意

有一个n*n的格子,刚开始每个格子都是白色的,现在把m个格子屠城了黑色,有没有涂成一个3 * 3的黑色格子,如果没有输出-1,如果有输出第一个出现3 * 3格子的最少操作步数

思路

开一个新的数组a,每次涂一个格子在a数组上把这个格子周围包括这个格子本身的9个格子+1,如果有一个格子的值为9,那么就出现了一个以这个格子为中心的3 * 3的黑色格子

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int e[1005][1005];
int nex[8][2]= {{1,0},{0,1},{-1,0},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
int main()
{
    int n,m;
    while(~scanf("%d %d",&n,&m))
    {
        int x,y,flag=0,a;
        memset(e,0,sizeof(e));
        for(int i=1; i<=m; i++)
        {
            scanf("%d %d",&x,&y);
            e[x][y]++;
            if(e[x][y]==9&&!flag)
            {
                flag=1;
                a=i;
            }
            if(!flag)
            {
                for(int j=0; j<8; j++)
                {
                    int tx=x+nex[j][0];
                    int ty=y+nex[j][1];
                    if(tx<=0||ty<=0||tx>n||ty>n)
                        continue;
                    else
                        e[tx][ty]++;
                    if(e[tx][ty]==9&&!flag)
                    {
                        flag=1;
                        a=i;
                    }
                }
            }
        }
        if(flag)
        {
            printf("%d\n",a);
        }
        else
            printf("-1\n");
    }
    return 0;
}

C - 水题C

HDU - 2141

中文题意就不解释了。
思路就是把前两个货架的值两两和预处理出来,然后遍历第三个货架,在预处理的和中二分。。。
这个题简直卡死我了。。。wa了18发。。我竟然还有勇气交。。是的wa了18发后A了。。。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
int a[505],b[505],c[505];
int d[250003];
int main()
{
    int x1,y1,z1,p=1,x,y,z;
    int f;
    while(~scanf("%d %d %d",&x1,&y1,&z1))
    {
        int flag=0;
        if(x1<=0||y1<=0||z1<=0)
            flag=1;
        for(int i=1; i<=x1; i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1; i<=y1; i++)
        {
            scanf("%d",&b[i]);
        }
        for(int i=1; i<=z1; i++)
        {
            scanf("%d",&c[i]);
        }
        int ans=0;
        for(int i=1;i<=x1;i++)
            for(int j=1;j<=y1;j++)
        {
            int k=a[i]+b[j];
                d[ans++]=k;
        }
        sort(d,d+ans);
        int T,n;
        scanf("%d",&T);
        printf("Case %d:\n",p++);
        while(T--)
        {
            scanf("%d",&n);
            if(flag)
            {
                printf("NO\n");
                continue;
            }
            int flag1=0;
            for(int i=1;i<=z1;i++)
            {
                int h=n-c[i];
                int l=0,r=ans-1;
                while(l<=r)
                {
                    int mid=(l+r)/2;
                    if(d[mid]==h)
                    {
                        flag1=1;
                        break;
                    }
                    if(d[mid]>h)
                        r=mid-1;
                    else
                        l=mid+1;
                }
            }
            if(flag1)
                printf("YES\n");
            else
                printf("NO\n");
        }
    }
    return 0;
}

·
·

D - 水题D

HDU - 1874

最短路的板子题,敲了一发板子就过了

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
    int v,w,nex;
};
node e[20005];
int f[1005],n,m,tot;
int dis[305],book[305];
const int inf=0x3f3f3f3f;
void init()
{
    tot=0;
    memset(f,-1,sizeof(f));
    memset(book,0,sizeof(book));
    for(int i=0;i<n;i++)
        dis[i]=inf;
}
void add(int u,int v,int w)
{
    e[tot].v=v;
    e[tot].w=w;
    e[tot].nex=f[u];
    f[u]=tot++;
}
int main()
{
    int s,t,x,y,z;
    while(~scanf("%d %d",&n,&m))
    {
        init();
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d %d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        scanf("%d %d",&s,&t);
        dis[s]=0;
        book[s]=1;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=f[u];i!=-1;i=e[i].nex)
            {
                int v=e[i].v;
                if(dis[v]>dis[u]+e[i].w)
                {
                    dis[v]=dis[u]+e[i].w;
                    if(book[v]==0)
                    {
                        q.push(v);
                        book[v]=1;
                    }
                }
            }
            book[u]=0;
        }
        if(dis[t]<inf)
            printf("%d\n",dis[t]);
        else
            printf("-1\n");
    }
    return 0;
}

·
·

E - 水题E

POJ - 3104

题意就不解释了。
思路:二分需要的时间,判断时间x内能不能让这N件衣服晾干:我们设一件衣服用吹风机的时间为x
则(mid-x)+x*k>=Ai,整理一下得x>=(Ai-mid)/(k-1),当k==1时,回发生除0错误,所以 k= =1时要特判一下

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
long long n,e[100005],k;
int F(long long mid)
{
    long long ans=0;
    for(long long i=1; i<=n; i++)
    {
        if(e[i]>mid)
        {
            long long t=e[i]-mid;
            ans+=t/k;
            if(t%k)
                ans++;
        }
    }
    if(ans<=mid)
        return 1;
    return 0;
}
int main()
{
    while(~scanf("%lld",&n))
    {
        long long r=-1;
        for(long long i=1; i<=n; i++)
        {
            scanf("%lld",&e[i]);
            r=max(r,e[i]);
        }
        scanf("%lld",&k);
        if(k==1)
        {
            printf("%lld\n",r);
            continue;
        }
        k--;
        long long ans=0,l=1;
        while(l<=r)
        {
            long long mid=(l+r)/2;
            if(F(mid))
            {
                ans=mid;
                r=mid-1;
            }
            else
                l=mid+1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

·
·

F - 水题F

CodeForces - 612D

题意

给你n个线段,输出k个线段覆盖的区间

思路

看到这个题的时候,感觉是线段并的问题,但是其实没有这么麻烦,只是利用了线段并的思想,我们把左端点记为1,右端点记为-1,从左到右扫描,如果扫描值为k那么这个时候有k条线段同时覆盖,当第一次小于k时,也就是我们要记录的右端点了。。模拟一下就好

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
    int flag,x;
};
node e[5000005];
struct Node
{
    int x,y;
};
Node b[5000005];
int cmp(node x,node y)
{
    if(x.x==y.x)
        return x.flag>y.flag;
    return x.x<y.x;
}
int main()
{
    int n,k;
    while(~scanf("%d %d",&n,&k))
    {
        int tot=0,x,y;
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d",&x,&y);
            e[tot].x=x;
            e[tot++].flag=1;
            e[tot].x=y;
            e[tot++].flag=-1;
        }
        sort(e,e+tot,cmp);
        int sum=0,flag=0;
        x=0;
        for(int i=0;i<tot;i++)
        {
            x+=e[i].flag;
            if(x>=k&&flag==0)
            {
                flag=1;
                b[sum].x=e[i].x;
            }
            if(flag&&x<k)
            {
                flag=0;
                b[sum++].y=e[i].x;
            }
        }
        printf("%d\n",sum);
        for(int i=0;i<sum;i++)
            printf("%d %d\n",b[i].x,b[i].y);
    }
    return 0;
}

·
·

G - 水题G

CodeForces - 1051C

虽然是中文题意,但是我还是想说一下这个独一无二,是对于男生和女生单独而言的。。。如果女生手里只有一颗这个糖,那么对于女生而言就是独一无二的。。。比赛的时候,以为是对于男生女生一起而言。。。好难过。。。
思路:
对于只有一颗的糖,他可以作为独一无二的糖给男生或者女生;
对于有两颗的糖,有两种情况:
1)全都给男生或者女生,也就是对于结果没有任何影响
2)一颗给男生一颗给女生,这两颗糖对于男生女生而言都是独一无二的糖,对结果也没有任何影响
对于有三颗及以上的糖来说:
1)其中一颗糖给男生或女生,其余的都给对方,则拿到一颗糖的一方独一无二的糖数加一
2)全都给男生或者女生,对结果没有影响
综上:当只有一颗糖的数量为奇数,且没有三颗及以上的糖的时候,输出NO,其余情况都可以

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[105],e[105],c[105];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(e,0,sizeof(e));
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            e[a[i]]++;
        }
        int x=0,y=0;
        for(int i=1; i<=100; i++)
        {
            if(e[i]==1)
                x++;
            else if(e[i]>2)
                y++;
        }
        if(x%2&&y==0)
            printf("NO\n");
        else
        {
            printf("YES\n");
            if(x%2==0)
            {
                int s=0;
                for(int i=1; i<=n; i++)
                {
                   if(e[a[i]]==1)
                   {
                       if(s%2)
                        printf("A");
                       else
                        printf("B");
                        s++;
                   }
                   else
                     printf("A");
                }
            }
            else
            {
                int s=0,flag=0;
                for(int i=1; i<=n; i++)
                {
                    if(e[a[i]]==1)
                    {
                        if(s%2)
                            printf("B");
                        else
                            printf("A");
                            s++;
                    }
                    else if(e[a[i]]>2&&!flag)
                    {
                        flag=1;
                        printf("B");
                    }
                    else
                        printf("A");
                }
            }
            printf("\n");
        }
    }
    return 0;
}

·
·

H - 水题H

POJ - 1821

这个连接就直接给原题连接吧。。(翻译的中文题意。。。根本看不懂,还好比赛的时候根本没看)

题意

一共有m个粉刷匠,一个长n的栅栏(每个栅栏编号1~n)
每个粉刷匠有三个值si,pi,li 分别代表着,这个粉刷匠坐在第si个栅栏前可以粉刷li个栅栏(必须是连续的并且包括第si个栅栏),粉刷一个栅栏可以赚pi元
问你这m个粉刷匠可以赚钱的最大值是多少

思路

设dp【i】【j】的意思是:第i个粉刷匠粉刷到第j个栅栏的时候能赚的最大钱是多少
那么dp【i】【j】可以转移的有三个方程
1)dp[i][j]=dp[i-1][j]:意思是,第i个粉刷匠没有刷栅栏,那么这个状态下得到的钱就是上一个粉刷匠粉刷的所赚的钱
2)dp[i][j]=dp[i][j-1]:第i个粉刷匠没有刷第j个栅栏
3)dp[i][j]=dp[i-1][k]+(j-k)*pi:第i-1个粉刷匠粉刷到底k个栅栏,第i个粉刷匠粉刷从k+1粉刷到第j个栅栏
所以,dp[i][j]=max(dp[i-1][j] , dp[i][j-1] , dp[i-1][k]+(j-k)*pi);
到这里基本的思路就理清楚了,但是在第三个状态下dp[i][j]=dp[i-1][k]+(j-k)*pi,我们发现还要枚举k,那么时间复杂度就太高了,当j不变的时候dp[i][j] = dp[i-1][j] + j * pi - k * pi,我们发现j * pi是不变的,我们只要找到dp[i-1][j] - k * pi的最大值就好。用优先队列维护一下

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
struct Node
{
    int p,v;
    Node(int V,int P)
    {
        p=P;
        v=V;
    }
    bool operator <(const Node &a)const
    {
        return this->v<a.v;
    }
};
struct node
{
    int s,p,l;
};
node e[105];
int dp[105][20000];
int cmp(node x,node y)
{
   return x.s<y.s;
}
int main()
{
    int n,m;
    while(~scanf("%d %d",&n,&m))
    {
        for(int i=1;i<=m;i++)
            scanf("%d %d %d",&e[i].l,&e[i].p,&e[i].s);
        sort(e+1,e+1+m,cmp);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=m;i++)
        {
            int si=e[i].s,pi=e[i].p,li=e[i].l;
            priority_queue<Node>q;
            for(int k=max(0,si-li);k<si;k++)
                q.push(Node(dp[i-1][k]-pi*k,k));
            for(int j=1;j<=n;j++)
            {
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                if(j<si||j>=si+li)
                    continue;
                while(!q.empty()&&q.top().p+li<j)
                    q.pop();
                if(q.empty())
                    continue;
                dp[i][j]=max(dp[i][j],q.top().v+pi*j);
            }
        }
        printf("%d\n",dp[m][n]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值