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;
}