Winter Is Coming
题意:
一共有N天,每天的气温已经给出,对应我们有两种轮胎,一种是冬季轮胎,一种是夏季轮胎,冬季轮胎可以在任何温度下使用,但是只能一共用K天(K天不必连续);
夏季轮胎只能在温度>=0的时候使用,没有限制天数。初始的时候是夏季轮胎
对应想要知道能不能度过整个冬天,如果可以,那么输出最少交换轮胎的次数,否则输出-1.
思路:(>=0度为暖天,<0度为冷天)
1.先记录下冬天的天数,判断对于题目给定的k能不能走完冷天,不能则输出-1,能则继续下一步。(同时记录最坏情况下换胎的次数)
2.如果k足够用的话,那么走完冷天还剩下的k就可以在暖天继续走,那么这样就可以利用贪心的思想来减少换胎的次数了。我们可以记录下前后冷天的间隔天数,当k大于它时,那么换胎次数就减少了两次。(注意要特判下最后一天)
(注意都为暖天时,就因为这个wrong了好久
)。

代码:
#include<stdio.h>
#include<algorithm>
const int maxn=200000+10;
using namespace std;
int a[maxn],b[maxn];
struct node
{
int x,y;
} s[maxn];
int main()
{
int n,m,i;
scanf("%d%d",&n,&m);
for(i=0; i<n; i++)
scanf("%d",&a[i]);
int k=0,ans=0;
for(i=0; i<n; i++)
{
if(a[i]<0)//记录低温的天数
k++;
if(i)
{
if((a[i]>=0&&a[i-1]<0)||(a[i-1]>=0&&a[i]<0))//最坏的情况下需要换胎的次数
ans++;
}
else if(a[0]<0)//注意冬天的第一天用的是夏胎
ans++;
}
if(k==0)//注意k=0时要特判
printf("0\n");
else if(k>m)
printf("-1\n");
else if(k==m)
printf("%d\n",ans);
else
{
k=m-k;//多余的冬胎使用天数
int cnt=0,t=0;
for(i=0; i<n; i++)
{
if(a[i]<0)
{
int j=i;
while(a[j]<0&&j<n)
j++;
s[cnt].x=i;//一次持续冷天的左端点
s[cnt].y=j-1;//右端点
if(cnt)
b[t++]=s[cnt].x-s[cnt-1].y-1;//记录前后持续冷天的间隔天数
i=j-1;
cnt++;
}
}
sort(b,b+t);//对间隔天数进行排序
for(i=0; i<t; i++)
{
if(b[i]<=k)
{
k-=b[i];
ans-=2;
}
else
break;
}
if(a[n-1]>=0)//特判下最后一天
{
b[t]=n-1-s[cnt-1].y;
if(b[t]<=k)
ans-=1;
}
printf("%d\n",ans);
}
return 0;
}