ZOJ4130
题目链接在此!
题目大意:
关灯问题。
总共n个灯,然后给状态,一次能关掉连续的m个灯。
关灯k次就能成功,问最少的m。
注意!不是改变状态!是关掉!0不会重新变成1的。
题目思路:
用二分的方法,让left=1,right=总灯数,key为每次熄灭的灯数,用num来记录总次数,只要num小于等于k即可,最后输出最小的key,也就是left。
这题是我亲爱的队友做的,我试着理解一下然后讲清楚。
我和她们代码风格还挺不一样的。
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <iomanip>
#include <cmath>
#include <map>
#include <stack>
#include <algorithm>
#include <queue>
#include <set>
#include <cstdio>
#define INF 0x3f3f3f3f
#define MAX 200100
#define ll long long
using namespace std;int N, K;
int dir[MAX];
//开全局了!要学习!int main()
{int T;scanf("%d", &T);while(T--){scanf("%d%d", &N, &K);getchar();//读入一个换行!for(int i = 0; i < N; i++){dir[i] = getchar() - '0';}//好接下来开始二分!int l = 1, r = N;while(l < r)//这一整段的操作:判断mid是否能使得操作次数小于k{int mid = (l + r) / 2;int cnt = 0;for(int j = 0; j < N; j++){if(dir[j] == 0)//灯是灭掉的!我们需要把1->0//跳过!直到找到需要关闭的灯。continue;j += mid - 1;//移动mid,等于说找到开着的灯然后把从他开始的mid个全关了。cnt++;//关灯次数}if(cnt <= K)//直到找到最小的k.{r = mid;}else{l = mid + 1;}}printf("%d\n", l);}return 0;
}
就很清楚!
怎么克服根深蒂固的自卑啊。