508B、C、E(贪心)

 B、给一个奇数,要通过交换任意两个数,将它变成可得到的最大的偶数。

奇数变偶数,显然只要把个位与其他位上任意一个偶数交换即可,要保证最大,则判断个位数是否大于当前位的偶数,若大于则交换即可,若个位数比其他各个位上的偶数都要小,则将它与最低位的偶数交换,这样可以保证最大。

#include<bits/stdc++.h>
using namespace std;
  char n[100005];
int main()
{
    int i;
    cin>>n;
    int L=strlen(n);
    int pos=-1;    //记录偶数所在的最低位
    bool flag=0;
    for(i=0;i<L-1;++i)
    {
        if(n[i]%2==0)
        {
            pos=i;
            if(n[i]<n[L-1])
            {
                swap(n[i],n[L-1]);
                flag=1;
                break;
            }
        }
    }
    if(!flag)    //将个位数与最低位的偶数交换
        swap(n[pos],n[L-1]);
    if(pos!=-1) puts(n);
    else puts("-1");
    return 0;
}





C、m只鬼在w[i]时刻来访,来访时要保证至少有r根蜡烛燃烧,点燃一根蜡烛需耗时1秒,每根蜡烛燃烧的持续时间均为t秒。求最少要点燃几根蜡烛。

由于点燃一根蜡烛要耗时1s,故如果r>t,则不可能保证同时有r根蜡烛燃烧。
若r<=t,则一定有解。因为可以每个时刻都点燃蜡烛,就可以保证每个时刻都至少有r根蜡烛燃烧。
用数组num来记录各个时刻的燃烧的蜡烛数目。只需保证在w[i]时刻有r支蜡烛燃烧即可,不足的话在鬼到访之前一刻补上即可。

#include<bits/stdc++.h>
using namespace std;
int w[305],num[1002];
int main()
{
    int m,t,r,i,j,ans=0;
    cin>>m>>t>>r;
    memset(num,0,sizeof(num));
    for(i=1;i<=m;++i) scanf("%d",&w[i]);
    if(t<r) puts("-1");
    else
    {
        for(i=1;i<=m;++i)
        {
            int n=r-num[w[i]];//所需的蜡烛
            if(n)
            {
                ans+=n;
                //更新各个时刻蜡烛数
                for(j=0;j<t-n+1;++j)  num[w[i]+j]+=n;// n根蜡烛同时燃烧的持续时间为t-n+1
                for(j=1;j<n;++j) num[w[i]+t-n+j]+=(n-j);
            }
        }
        printf("%d\n",ans);
    }

    return 0;
}




E、n对括号,按照左括号出现的次序编号,给出各对括号左、右括号之间的距离所在的区间[L,R],输出原括号序列。


对于第i对括号,设其左括号出现的位置为pos,则右括号出现在[ pos+L[i],pos+R[i] ]的位置区间。
每输入一个区间,将区间入栈。如果右括号与当前的左括号的距离在当前栈顶的位置区间之内,则二者匹配,这样可保证下一对括号尽可能匹配得上。

若距离大于位置区间的右边界,则将无法匹配。

#include<bits/stdc++.h>
using namespace std;
char s[1205];

stack<int>L,R;
int main()
{
    int n,i,l,r;
    cin>>n;
    memset(s,0,sizeof(s));
    int pos=0;
    for(i=1;i<=n;++i)
    {
        s[pos]='(';
        scanf("%d %d",&l,&r);
        L.push(pos+l);R.push(pos+r);
        ++pos;    //当前位置,亦即与当前的‘('相距的距离。
        while(!L.empty()&&L.top()<=pos&&pos<=R.top())
        {
            s[pos++]=')';
            L.pop(),R.pop();
        }
        if(!L.empty()&&pos>R.top())    //已经超出区间范围。
        {
            puts("IMPOSSIBLE");
            return 0;
        }
    }
    if(!L.empty()) puts("IMPOSSIBLE");    //距离无法到达区间的左边界
    else puts(s);
    return 0;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值