D: 题意:一行1*n的格子放船只,船数为a,船的长度为b,每格为0或1,1表示该格并不是船只的一部分,找出最少的格子数使得射击这些格子至少能打中一艘船。
思路:船的长度为b,即每段连续的长度为b的0的串都可以放下一只船,射击点为最后一个格子时最优,找出所有的可以放船的位置res个,选择其中的res-a+1个位置。
#include<bits/stdc++.h>
using namespace std;
char str[];
int op[]={};
int main() {
int n,a,b,k,cnt=,tmp,l,t=;
scanf("%d%d%d%d%s",&n,&a,&b,&k,str);for(int i=;i<n;++i) {
if(str[i]=='') ++t;
if(str[i]=='') t=;
if(t==b) {
op[cnt++]=i+;
t=;
}
}
cnt-=a-;
printf("%d\n",cnt);
for(int i=;i<cnt;++i) {
printf("%d%c",op[i],(i==cnt-)?'\n':' ');
}
return ;
}
E 题意:一个公司有n个人,只有一个主管编号为s,除主管外的n-1个人有且仅有一个直接上司,但他的直接上司的上司也算他的上司。给出一个数列为1-n号员工的上司的数目,问至少修改几个值使得该数列为正确。
思路:要想使得数列正确,数列必须为连续的非降数列,如0111234,且数列中的0只有一个且编号为s。
如果数列发生错误,则肯定是出现断裂或编号不为s的0,如00234,编号不为s的0必为要修改的,每次出现断裂时先用0补断裂,然后不断用目前最大的数补断裂,如果无数可补,则答案+1,结束。
#include<bits/stdc++.h>
using namespace std;
int a[]={},cnt=;
int main() {
int n,s,last,ans=;
scanf("%d%d",&n,&s);
for(int i=;i<=n;++i) {
scanf("%d",&a[i]);
if(i!=s&&!a[i]) ++cnt;
}
if(a[s]!=) ++ans,a[s]=;
sort(a+,a+n+);
last=n;
int x=upper_bound(a+,a+n+,)-a;
if(x==n) {
printf("%d\n",cnt+ans);
return ;
}
int f=;
for(int i=x;i<=last&&f;++i) {
while(a[i]>a[i-]+) {
if(cnt) --cnt,++a[i-];
else {
if(last>i) {
--last,++a[i-];
}
else {
++ans;
f=;
break;
}
}
++ans;
}
}
printf("%d\n",ans+cnt);
return ;
}