MAXVAC - Editorial

This was a really nice problem :relieved:
My solution if any one wants to refer
https://www.codechef.com/viewsolution/57197838

#include <bits/stdc++.h>
#define int long long int
using namespace std;

void solve()
{
	int n, x;
	cin >> n >> x;
	string str;
	cin >> str;
	int left[n];
	int right[n];
	int zero_count = 0;
	int temp_ans = 0;
	int final_ans = 0;
	for (int i = 0; i < n; ++i)
	{
		if (str[i] == '1')
		{
			left[i] = zero_count;
			zero_count = 0;
		}
		else {
			zero_count++;
			left[i] = -1;
		}

	}
	zero_count = 0;
	for (int i = n - 1; i >= 0; --i)
	{
		if (str[i] == '1')
		{
			right[i] = zero_count;
			zero_count = 0;
		}
		else {
			zero_count++;
			right[i] = -1;
		}

	}
	zero_count = 0;
	for (int i = 0; i < n; ++i)
	{
		if (str[i] == '0')
			zero_count++;
		else
		{
			temp_ans += (zero_count / x);
			zero_count = 0;
		}
	}
	if (str[n - 1] != '1')
		temp_ans += (zero_count / x);
	// cout << temp_ans << endl;
	for (int i = 0; i < n; ++i)
	{
		if (left[i] == 0)
			continue;
		else
		{
			int temp;
			temp = temp_ans;
			temp -= (left[i] / x);
			temp -= (right[i] / x);
			temp += (left[i] + right[i] + 1) / x;
			final_ans = max(final_ans, temp);
		}
	}
	cout << final_ans << endl;


}

int32_t main()
{
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int tc = 1;
	cin >> tc;
	while (tc--)
	{
		solve();
	}

}
2 Likes

Can someone explain what’s wrong with my code? I am first calculating the positions of ones in the string to find the longest segment of zeros. Then I am calculating the remaining groups of zeros to check if they contribute anything to the number of vacations. If they contribute, then I am adding them to the original sum.

void solve() {
	int n, x; cin >> n >> x;
	string s; cin >> s;

    // For string with length less than 2 
	if(s.length() < 2) {
		cout << 1/x << "\n";
		return;
	}

    // Keep track of positions of 1's to calculate zeros between two 1's
	vector<int> ones;
	ones.pb(0);
	for(int i = 0; i < n; i++) {
		if(s[i] == '1')
			ones.pb(i);
	}
	ones.pb(s.length() - 1);

	int curr = -INF;
	int idx = 0;

    // Calculate the length of maximum segment of ones
	for(int i = 1; i < ones.size() - 1; i++) {
		int sum = 0;
		if(s[ones[i - 1]] == '1') {
			sum += ones[i] - ones[i - 1] - 1;
		}
		else
			sum += ones[i] - ones[i - 1];

		if(s[ones[i+1]] == '1') {
			sum += ones[i+1] - ones[i] - 1;
		}
		else
			sum += ones[i+1] - ones[i];

		if(sum > curr) {
			curr = sum;
			idx = ones[i];
		}
	}

    // Calculate the remaining groups of zeros to check if they contribute to the vacations days
	vector<int> zeros;
	int cnt = 0;

	int nid = -1;
	for(int i = idx + 1; i < n; i++) {
		if(s[i] == '1') {
			nid = i;
			break;
		}
	}

	if(nid != -1) {
		for(int i = nid; i < n; i++) {
			if(s[i] == '0')
				cnt++;
			else {
				zeros.pb(cnt);
				cnt = 0;
			}
		}
		zeros.pb(cnt);
	}

	int days = (curr + 1) / x;
	
	for(int i : zeros) {
		days += (i / x);
	}

	cout << (curr == -INF ? s.length() / x : days) << "\n";


}

Blockquote
Can any one tell where my code fails ?

#include <bits/stdc++.h>

using namespace std;

void solve(){
	int n,x;
	string str;
	cin >> n >> x;
	cin >> str;
	vector<int> v,diff;
	int pos = 0;
	for(auto x: str){
		if(x == '1')v.push_back(pos);
		pos++;
	}
	int ans = 0,len = v.size();
	if(len != 0){
		ans += (v[0]/x);
		diff.push_back(v[0] % x);
		for(auto it = 0;it < len - 1;++it){
			int temp = (abs(v[it] - v[it+1]) - 1)%x;
			ans += (abs(v[it] - v[it+1]) - 1)/x;
			diff.push_back(temp);
		}
		ans += (n - v[len-1]-1)/x;
		diff.push_back((n - v[len - 1] - 1)%x);
		if(diff.size() == 1 && diff[0] == x - 1)ans++;
		else{
			int l = diff.size();
			for(int i = 0;i<l - 1;++i){
				if(diff[i] + diff[i + 1] == x - 1){
					ans++;
					break;
				}
			}
		}
	}
	else ans = (n/x);
	cout << ans << "\n";
	
}

int main(){
	ios_base::sync_with_stdio(false); 
	cin.tie(NULL);
	int64_t test;
	cin >> test;
	while(test--){
		solve();
	}
}

as yellow_tee said:
try
N= 13
X= 5
0000001001000

import java.util.;
import java.lang.
;
import java.io.*;
class Codechef
{
public static void main (String[] args) throws java.lang.Exception
{
Scanner sc=new Scanner(System.in);
int test=sc.nextInt();
while(test>0)
{
int n=sc.nextInt();
int x=sc.nextInt();
sc.nextLine();
String s=sc.nextLine();
Stack st=new Stack();
ArrayList list=new ArrayList();
for(int i=0; i<n; i++)
{
if(s.charAt(i)==‘0’)
st.push(‘0’);
else
{
// System.out.println(“BeforeStack”+st);
int count=0;
while(st.size()>0 && st.peek()!=‘1’)
{
count++;
st.pop();
}
// System.out.println(“AfterStack”+st);
if(list.size()==0)
list.add(count);
else
{
// System.out.println(“BeforeList”+list+" “+count);
if(st.size()>0)
{
int elem=list.get(list.size()-1)+count+1;
int indx=list.size()-1;
list.set(indx,elem);
st.pop();
}
else
{
list.set(list.size()-1,list.get(list.size()-1)+count);
}
list.add(count);
// System.out.println(“AfterList”+list+” "+count);
}
st.push(‘1’);
//System.out.println(list);
}
}
int count=0;
while(st.size()>0 && st.peek()!=1)
{
count++;
st.pop();
}
if(st.size()>0)
{
if(list.size()>0)
list.set(list.size()-1,list.get(list.size()-1)+count+1);
}
else
{
if(list.size()>0)
list.set(list.size()-1,list.get(list.size()-1)+count);
}
list.add(count);
// System.out.println(list);
Collections.sort(list);
System.out.println((list.get(list.size()-1))/x);
test–;
}
}
}

can you please tell me on which test case this solution will fail??

import java.util.;
import java.lang.
;
import java.io.*;
class Codechef
{
public static void main (String[] args) throws java.lang.Exception
{
Scanner sc=new Scanner(System.in);
int test=sc.nextInt();
while(test>0)
{
int n=sc.nextInt();
int x=sc.nextInt();
sc.nextLine();
String s=sc.nextLine();
Stack st=new Stack();
ArrayList list=new ArrayList();
for(int i=0; i<n; i++)
{
if(s.charAt(i)==‘0’)
st.push(‘0’);
else
{
// System.out.println(“BeforeStack”+st);
int count=0;
while(st.size()>0 && st.peek()!=‘1’)
{
count++;
st.pop();
}
// System.out.println(“AfterStack”+st);
if(list.size()==0)
list.add(count);
else
{
// System.out.println(“BeforeList”+list+" “+count);
if(st.size()>0)
{
int elem=list.get(list.size()-1)+count+1;
int indx=list.size()-1;
list.set(indx,elem);
st.pop();
}
else
{
list.set(list.size()-1,list.get(list.size()-1)+count);
}
list.add(count);
// System.out.println(“AfterList”+list+” "+count);
}
st.push(‘1’);
//System.out.println(list);
}
}
int count=0;
while(st.size()>0 && st.peek()!=1)
{
count++;
st.pop();
}
if(st.size()>0)
{
if(list.size()>0)
list.set(list.size()-1,list.get(list.size()-1)+count+1);
}
else
{
if(list.size()>0)
list.set(list.size()-1,list.get(list.size()-1)+count);
}
list.add(count);
// System.out.println(list);
Collections.sort(list);
System.out.println((list.get(list.size()-1))/x);
test–;
}
}
}

can you please tell me on which test case it will give wrong answer

why i am getting WA for this solution:
#include <bits/stdc++.h>
using namespace std;

int main()
{
// your code goes here
int t;
cin>>t;
while(t–)
{ string s;
int n,k;
cin>>n>>k;
cin>>s;
int ar[n];
string st[n];
int ct=0;
for(int i=0;i<s.size();i++)
{
if(s[i]==‘1’)
{
st[ct]=s;
st[ct][i]=‘0’;
ct++;
}

     }
      int br[1000000];
     for(int it=0;it<ct;it++)
     {
         
 int flag=0;
 for(int i=0;i<s.size();)
 {
      if(s[i]=='0')
      {     int j;
            for(j=i;j<i+k;j++)
            {
                 if(s[i]=='0')
                 continue;
                 else
                 break;
            }
            if(j==i+k)
            {
            flag++;
            i=i+k;
            }
      }
      else
      {
           i++;
      }
 }
 br[it]=flag;
  
     }

sort(br,br+ct);
cout<<br[ct-1]<<endl;

}

return 0;

}

Solved in a bit easy way!

my solution : CodeChef: Practical coding for everyone.
time comp. : O(N).
Hope it helps! :grinning_face_with_smiling_eyes:

I calculated prefix and suffix and check if i flip 1 to 0 then total number of consecutive 0 and take max of that
It is giving CORRECT ON SUBTASK 1 but WA on any other why

void solve()
{
   int n,x; cin>>n>>x;
   string bin; cin>>bin;
   
   vector<int> pre(n);
   vector<int> suf(n);
   
   int count = 0;
   for(int i = 0;i<n;i++)
   {
           if(bin[i]=='0')
           {
                count++;
                pre[i]=count;
           }
           else{
                pre[i]=count;
                count=0;
           }
   }
    count=0;
   for(int i = n-1;i>=0;i--)
   {
           if(bin[i]=='0')
           {
                count++;
                suf[i]=count;
           }
           else{
                suf[i]=count;
                count=0;
           }
   }
   int m=-1;
   for(int i= 0;i<n;i++)
   {
           int local = 0;
           if(bin[i]!='0')
           local = pre[i]+suf[i]+1;
           else 
           local = pre[i]+suf[i]-1;
           m=max(m,local);
   }
   int xx  = ceil(m/x);
   cout<<ceil(m/x);
}

int32_t main()
{
    sync;
    int t = 1;
    cin>>t;
    while(t--){
        solve();
        cout<<"\n";
    }
    return 0;
}

One thing we can observe is that by taking an extra holiday, you can improve the number of vacations by no more than 1.

i.e., if \text{orig\_ans} is the maximum number of vacations without taking extra holiday, then by taking 1 extra holiday, we can get no more than (\text{orig\_ans} + 1) vacations.

Now, it looks easier - we can iterate over all i where s[i] = 1 and check if we can get 1 extra vacation.

Implementation: CodeChef: Practical coding for everyone

Because you are calculating only the segment of zeroes where you flipped the ‘1’. There can be other segments of ‘0’ that can contribute to vacations without flipping any bit .
For example
N = 15 and X =3
100010100000001
Your m will be 9 (index = 5 to 13 ) and hence final answer is just 9/3=3
But you also have to add the segment of zeroes from index = 1 to 3. Hence correct answer is 1+3=4

1 Like

thanks bhai!!! 2 ghante tk sochta rha isko mai!!

1 Like
#include <bits/stdc++.h>
using namespace std;
#define sync {ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);}
#define rep(n) for(int i = 0;i<n;i++)
#define rep1(a,b) for(int i = a;i<b;i++)
#define int long long int
#define mod 1000000007


void solve()
{
   int n,x; cin>>n>>x;
   string bin; cin>>bin;
   
   vector<int> pre(n);
   vector<int> suf(n);
   
   int count = 0;
   for(int i = 0;i<n;i++)
   {
           if(bin[i]=='0')
           {
                count++;
                pre[i]=count;
           }
           else{
                pre[i]=count;
                count=0;
           }
   }
    count=0;
   for(int i = n-1;i>=0;i--)
   {
           if(bin[i]=='0')
           {
                count++;
                suf[i]=count;
           }
           else{
                suf[i]=count;
                count=0;
           }
   }
   int m=-1;
   int pos = -1;
   for(int i= 0;i<n;i++)
   {
           int local = 0;
           if(bin[i]!='0')
           local = pre[i]+suf[i]+1;
           else 
           local = pre[i]+suf[i]-1;
           if(m<local)
           {
                m = local;
                pos = i;
           }
   }
   bin[pos] = '0';
   int ans = 0;
   count=0;
  // cout<<pos<<"\n";
   for(int i = 0;i<n;i++)
   {
           if(bin[i] == '0')
           count++;
           else{
           //cout<<count<<" \n";
           ans += count/x;
           count = 0;
           }
   }
   ans+= count/x;
   
   
  cout<<ans;
}

int32_t main()
{
    sync;
    int t = 1;
    cin>>t;
    while(t--){
        solve();
        cout<<"\n";
    }
    return 0;
}

same isssue aarha hai bhai

when the holiday is taken on ithi^{th}ith day, and finally take the maximum of all these numbers.

See this

What is your output for this test case?
1
13 5
0000001001000

Correct Answer = 2
I think yours should be coming 1.

1 Like

yes

simple as af

You are selecting the longest subarray having at most one ‘1’.
This will not give the correct answer always as in this test case.
First you calculate the answer in the original string without flipping any ‘1’.
Then for every ‘1’ position, see by flipping which ‘1’ increases your answer.
Lets the initial answer is ans.
At any position i such that str[i]==‘1’ , you have pre[i] and suff[i].
Then do this :-

int temp = ans;
temp -= pre[i]/x;
temp -=suff[i]/x;
temp +=(pre[i] + suff[i] +1 )/x  ;
// +1 because you are flipping str[i]=='1' position
final_ans = max(final_ans,temp);

You can refer my code if you want
https://www.codechef.com/viewsolution/57197838
(Line 57 to 72)

1 Like

THanks bhai I misunderstood the question

got the approach but unable to implement it
any suggestion i am getting intutions for the problems but unable to implement it :slightly_frowning_face: :cry: :cry: