牛客寒假算法基础集训营6

A.出题
分析:首先如果有解,必满足\(6 \times m \leq n \leq 9 \times m\),我们设6的个数为\(X\),则剩余的个数为\(m-X\),剩余的分值为\(n-6 \times X\),所以此时满足条件必有如下式子:\(7 \times (m-X) \leq n-6 \times X \leq 9 \times (m-X)\),化简以后最终所求为 \(max(0,7 \times m-n)\)

#include "bits/stdc++.h"
using namespace std;
typedef long long LL;
LL n,m;
int main()
{
    scanf("%lld%lld",&n,&m);
    if(n<6*m||(n>9*m)) printf("jgzjgzjgz\n");
    else printf("%lld\n",max((LL)0,7*m-n));
    return 0;
}

B.煤气灶
分析:用等差数列求和公式,然而求解一个一元二次方程,直接二分答案即可

#include "bits/stdc++.h"
using namespace std;
typedef long long LL;
LL n,m,d,x;
bool judge(LL k){
    if((k*(k-1)*d)>=(2*m-2*n*k)) return true;
    return false;
}
int main()
{
    scanf("%lld%lld%lld%lld",&n,&m,&d,&x);
    LL l=0,r=x,ans=x;
    while(l<=r){
        LL mid=(l+r)/2;
        if(judge(mid)){
            ans=mid;
            r=mid-1;
        }else l=mid+1;
    }
    printf("%lld\n",ans);
}

C.项链
分析:贪心尽量选择价值大的来匹配,注意存在n大于总价值的情况

#include "bits/stdc++.h"
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
struct node{
    LL a,b;
}p[maxn];
int n,m;
bool cmp(node x,node y){
    return x.b>y.b;
}
LL dp[maxn];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) scanf("%lld",&p[i].a);
    for(int i=1;i<=m;i++) scanf("%lld",&p[i].b);
    sort(p+1,p+1+m,cmp);
    for(int i=1;i<=m;i++){
        dp[i]=dp[i-1]+p[i].a;
    }
    int pos=m;
    for(int i=1;i<=m;i++){
        if(dp[i]>=n){
            pos=i; break;
        }
    }
    LL sum=0;
    for(int i=1;i<=pos-1;i++) sum+=p[i].a*p[i].b;
    sum+=(n-dp[pos-1])*p[pos].b;
    LL mx=0;
    for(int i=1;i<=m;i++) mx+=p[i].a*p[i].b;
    printf("%lld\n",min(mx,sum));
    return 0;
}

D.美食
分析:不管当前是奇数还是偶数,都尽量用完,如果有剩余,就往下一个累计

#include "bits/stdc++.h"
using namespace std;
typedef long long LL;
const int maxn=1e5+100;
LL a[maxn];
int n;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    LL sum=0;
    for(int i=1;i<=n;i++){
        sum+=a[i]/2;
        if(a[i+1]>0&&(a[i]%2)){
            sum++;
            a[i+1]--;
        }
    }
    printf("%lld\n",sum);
    return 0;
}

E.海啸
分析:我们让小于d的为0,大于等于d的为0。这样很容易把问题转化为一个二维前缀和问题。二维前缀和的求解方法是:
预处理的时候有:
dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+a[i][j];
求解\((x_1,y_1)(x_2,y_2)\)构成的矩阵的和有
dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1]

#include "bits/stdc++.h"
using namespace std;
int n,m,d,q;
int main()
{
    scanf("%d%d%d",&n,&m,&d);
    int a[n+10][m+10],dp[n+10][m+10];
    memset(a,0,sizeof(a));
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            int x; scanf("%d",&x);
            if(x>=d) a[i][j]=1;
            else a[i][j]=0;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+a[i][j];
    }
    int q;
    scanf("%d",&q);
    while(q--){
        int x1,y1,x2,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        printf("%d\n",dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1]);
    }
    return 0;
}

F.石头剪刀布
分析:这题出得非常好,做法是思维+递归。首先,如果我们知道最后剩下的是哪个,一定可以通过DFS构造出这个序列。因为我们必然可以知道它本身和它可以打败的,在题目中,我们定义本身为i,则它可以打败的为(i+2)%3。然后我们在做一个字典序的判断即可。

#include "bits/stdc++.h"
using namespace std;
int P,R,S,p,r,s,L;
string dfs(int i,int l){
    if(l==L){
        if(i==0){++r,++s; return "RS";}
        if(i==1){++p,++r; return "PR";}
        if(i==2){++p,++s; return "PS";}
    }
    string a=dfs(i,l<<1),b=dfs((i+2)%3,l<<1);
    if(a+b>b+a) return b+a;
    return a+b;
}
int main()
{
    scanf("%d%d%d",&R,&P,&S);
    L=R+P+S;
    for(int i=0;i<3;i++){
        r=p=s=0;
        string res=dfs(i,2);
        if(r==R&&p==P&&s==S){
            cout<<res<<endl;
            return 0;
        }
    }
    cout<<"IMPOSSIBLE"<<endl;
    return 0;
}

G.区间或和
分析:这是一道很好的思维题,显然a=b的时候,答案就是a,那当a!=b的时候呢?首先我们求出a与b二进制下不同的最高位,显然根据或的性质,所有比这一位高的位都是原来的值。那么比这一位低的呢?因为取遍了[a,b]区间内的所有数,所以比它低的每一个二进制位至少有一个是0,所以比它低的位全为0

#include "bits/stdc++.h"
using namespace std;
typedef long long LL;
LL a,b;
int main()
{
    while(scanf("%lld%lld",&a,&b)!=EOF){
        LL c=a^b;
        LL x=1;
        while(x<=c) x*=2;
        printf("%lld\n",a|b|x-1);
    }
    return 0;
}

H.肥猪
分析:首先枚举会进行2操作的次数step,则对于一个位置i,它如果由2操作变换过来,则它一定由j变换过来,同时\(i-step \leq j \leq i\)。所以我们只需要枚举在这个范围内最小的a[j]即可,这样在加上\(step \times X\),就是最终的结果。区间最小值用线段树维护一下即可

#include "bits/stdc++.h"
using namespace std;
const int maxn=2e3+100;
typedef long long LL;
struct node{
    int left,right;
    LL Min;
}tree[maxn<<2];
int n;
LL x;
void pushup(int rt){
    tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min);
}
void build(int l,int r,int rt){
    tree[rt].left=l,tree[rt].right=r;
    tree[rt].Min=INT64_MAX;
    if(l==r){
        scanf("%lld",&tree[rt].Min);
        tree[rt].left=l,tree[rt].right=r;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    pushup(rt);
}
LL query(int l,int r,int rt){
    int L=tree[rt].left,R=tree[rt].right;
    if(l==L&&r==R) return tree[rt].Min;
    int mid=(L+R)>>1;
    if(r<=mid) return query(l,r,rt<<1);
    if(l>mid) return query(l,r,rt<<1|1);
    return min(query(l,mid,rt<<1),query(mid+1,r,rt<<1|1));
}
int main()
{
    scanf("%d%lld",&n,&x);
    build(1,n,1);
    LL ans=INT64_MAX;
    for(int i=0;i<n;i++){
        LL res=i*x;
        for(int j=1;j<=n;j++){
            if(j-i<1){
                if(j-i==0) res+=min(query(1,j,1),query(n,n,1));
                else res+=min(query(1,j,1),query((j-i+n)%n,n,1));
            }else res+=query(j-i,j,1);
        }
        ans=min(ans,res);
    }
    printf("%lld\n",ans);
    return 0;
}

I.wzoi
分析:这个题做法也很显然,用一个栈来维护,如果当前元素和栈顶相同,则+10分,否则把当前元素压栈。这样我们一定能把所有10分的全部求完,剩下栈中的部分一定是5分的。

#include "bits/stdc++.h"
using namespace std;
const int maxn=1e6+100;
string str;
int a[maxn];
int main()
{
    cin>>str;
    int n=str.length();
    for(int i=1;i<=n;i++){
        a[i]=str[i-1]-'0';
    }
    stack<int>s;
    int sum=0;
    for(int i=1;i<=n;i++){
        if(s.empty()){
            s.push(a[i]);
        }else{
            if(a[i]==s.top()){
                sum+=10;
                s.pop();
            }else{
                s.push(a[i]);
            }
        }
    }
    sum+=s.size()/2*5;
    printf("%d\n",sum);
    return 0;
}

J.迷宫
分析:直接BFS把队列跑空,则能够遍历到所有能达到的点,注意标记一下左右的次数

#include "bits/stdc++.h"
using namespace std;
const int maxn=1000+10;
int vis[maxn][maxn],n,m,r,c,x,y;
char s[maxn][maxn];
struct node{
    int x,y;
    int l,r;
}p[maxn*maxn];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int ans;
bool judge(int a,int b){
    if(a<1||a>n||b<1||b>m||s[a][b]=='*'||vis[a][b])
        return false;
    return true;
}
void bfs()
{
    node t;
    t.x=r,t.y=c;
    t.l=x,t.r=y;
    queue<node>que;
    que.push(t);
    vis[t.x][t.y]=1;
    while(!que.empty()){
        node tmp=que.front();
        que.pop();
        ans++;
        vis[tmp.x][tmp.y]=1;
        for(int i=0;i<4;i++){
            int nx=tmp.x+dx[i];
            int ny=tmp.y+dy[i];
            if(judge(nx,ny)){
                vis[nx][ny]=1;
                node res;
                if(i==0||i==1){
                    res.x=nx,res.y=ny;
                    res.l=tmp.l,res.r=tmp.r;
                    que.push(res);
                }
                if(i==2&&tmp.l){
                    res.x=nx,res.y=ny;
                    res.l=tmp.l-1,res.r=tmp.r;
                    que.push(res);
                }
                if(i==3&&tmp.r){
                    res.x=nx,res.y=ny;
                    res.l=tmp.l,res.r=tmp.r-1;
                    que.push(res);
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    scanf("%d%d%d%d",&r,&c,&x,&y);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cin>>s[i][j];
    }
    bfs();
    printf("%d\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/gzgywh/p/10713348.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的纺织品企业财务管理系统,源码+数据库+毕业论文+视频演示 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对纺织品企业财务信息管理的提升,也为了对纺织品企业财务信息进行更好的维护,纺织品企业财务管理系统的出现就变得水到渠成不可缺少。通过对纺织品企业财务管理系统的开发,不仅仅可以学以致用,让学到的知识变成成果出现,也强化了知识记忆,扩大了知识储备,是提升自我的一种很好的方法。通过具体的开发,对整个软件开发的过程熟练掌握,不论是前期的设计,还是后续的编码测试,都有了很深刻的认知。 纺织品企业财务管理系统通过MySQL数据库与Spring Boot框架进行开发,纺织品企业财务管理系统能够实现对财务人员,员工,收费信息,支出信息,薪资信息,留言信息,报销信息等信息的管理。 通过纺织品企业财务管理系统对相关信息的处理,让信息处理变的更加的系统,更加的规范,这是一个必然的结果。已经处理好的信息,不管是用来查找,还是分析,在效率上都会成倍的提高,让计算机变得更加符合生产需要,变成人们不可缺少的一种信息处理工具,实现了绿色办公,节省社会资源,为环境保护也做了力所能及的贡献。 关键字:纺织品企业财务管理系统,薪资信息,报销信息;SpringBoot
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值