Today in an exam I faced a problem which is Toggled Switches(Hacker Earth) as it is an exam question So, I am unable to send the question or its link (exactly).
Problem: we have to print a number representing the number of times do bulb changed its state. The bulb is attached to the "n" number of switches. So the bulb will be in the "on" state only when half or more than half of the given n of switches to be "on".
1 represents on state
0 for off respectively.
There is also a query that will be given to represent which switch has to be toggled ( change from on to off or vice-versa 1 ->0 or 0->1). So, by toggling may or may not the bulb state change. so we have to return the number of times it changed its state.
input:
1 - number of test case
3 - number of switches (n)
1 1 0 - initial all n switches states
3 - number of switches to be toggled
3 2 1 -> (3 represents third switch ie as index wise second in switches array.) switches that have to be toggled.
output:
1 - number of times the bulb changed its state.
explanation : initial array or switches state [1, 1, 0] as half or more than half switches are in on. hence bulb is in on state. as per queries [3,2,1]
we have to toggle the 3 rd switch. As initially third is in off [1,1,0] after toggling it changes to on [1,1,1] present switches state. as all are in on position bulb is on. ( no changes in the state of the bulb)
Now, have to toggle 2 nd switch so [1,1,1] changes to [1,0,1] switches states as half switches are on the bulb is on. ( no changes in the state of the bulb)
Now, 1 st switch to be toggled. Hence [1,0,1] changes to [0,0,1]. as not equal or more than half switches are in on states hence bulb is going to be off. ( now bulb state is changed)
Hence the output is one.
I wrote the answer to this I am only able to solve the sample test case. No hidden test case is got the right answer and some got time exceeds error. so totally 0 marks.
I am a beginner so please explain vividly where I am wrong what is wrong? how it can be efficient?.
and my code is
import java.util.*;
public class Main{
static Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
int test_cases = scan.nextInt();
while(test_cases>0){
//number of switches
int n = scan.nextInt();
// contains on / off positions of switches
int [] switches = new int[n];
for(int i =0;i<n;i++)
switches[i]=scan.nextInt();
//number of queries
int q = scan.nextInt();
// starts at 1 i.e queries[0]=1 but represents switch index 1(queries representing switch position and tha position starts from 1)
int [] queries = new int[q];
for(int i =0;i<q;i++)
queries[i]=scan.nextInt();
int result = toggled(n,switches,q,queries);
System.out.println(result);
test_cases--;
}
}
static int toggled(int n,int switches[],int q,int queries[]){
if(n==1)
return q;
int result =0;
//giving switch state on or off
boolean initial = on(switches);
//System.out.println("initial is "+initial);
//to represent on or off for all toggle including initial
boolean [] states = new boolean[q+1];
states[0] = initial;
int count = 0;
//to represent index of states
int state_count =1;
while(count<q){
if((switches[queries[count]-1] & 1 )== 1)
switches[queries[count]-1] = 0;
else
switches[queries[count]-1] = 1;
states[state_count++]=on(switches);
count++;
}
//System.out.println("state_count is "+state_count);
for(int i =1;i<state_count;i++){
if(initial ^ states[i] )
{
result+=1;
initial = states[i];
}
}
return result;
}
//method to evaluate whether to consider on or off ( to on(bulb) have to on atleast half of the switches)
static boolean on(int arr[]){
int sum = 0;
for(int i =0;i<arr.length;i++)
sum+=arr[i];
if(sum>=arr.length/2.0)
return true;
else
return false;
}
}
It seems like your on()
function is taking n
(linear) time where n
is the number of switches. Total time complexity would be O(n*q)
q is a number of queries. You can bring it down to O(n+q)
.
I am not familiar with Java therefore Python
Text after # denotes a comment in Python
def on(number_of_on, n) : # //takes O(1)
'''// Returns 1 if more than half or half of the switches are ON else returns 0'''
if (number_of_on >= n/2) :
return 1 #// ON STATE
else :
return 0 #// OFF state
for t in range(int(input())) : #// test cases (1)
n = int(input()) #// number of switches (3)
switches = list(map(int, input().split())) #// initial state of switches(1 1 0)
q = int(input()) #// number of queries (3)
queries = list(map(int, input().split())) #// toggle sequence (3 2 1)
number_of_on = 0 #// denote number of bulbs which are ON
count = 0 #// number of changes (ANSWER)
for i in range(n) : #// O(n)
if switches[i] == 1 :
number_of_on += 1
current = on(number_of_on, n) #// FUNCTION CALL
for i in range(q) : #// ITERATING IN QUERIES
if switches[queries[i]-1] == 1 : #// IF switch at 'q' is 1 (ON)
switches[queries[i]-1] = 0 #// TURNING it OFF
number_of_on -= 1 #// number of OFF will be (-1)
if on(number_of_on, n) == False and current == 1 : #// if on() returns False/0 (OFF) AND current is ON/1
current = 0 #// change current state
count += 1 #// count++ (change in state)
else :
switches[queries[i]-1] = 1
number_of_on += 1
if on(number_of_on, n) == True and current == 0 : #// if on() returns TRUE/1 (ON) AND current is OFF/0
current = 1 #// change current state
count += 1 #// count++ (change in state)
print(count) #// ANSWER
Function on(number_of_on, number_of_switches) // Returns 1 if more than half or half of the switches are ON else returns 0
n // number of switches (3)
- input switches // initial state of switches(1 1 0)
- input q // number of queries (3)
- input queries // toggle sequence (3 2 1)
- input number_of_on = 0 // denote number of bulbs which are ON
count = 0 // number of changes (ANSWER)
Firstly counting the number of switches that are ON and will store them in the variable number_of_on
will take O(n)
time.
and see the current state of the bulb by calling a function on(number_of_on, number_of_switches)
and assign value to the current
variable.
Then iterate over the queries (i - for loop variable)
if the value at element at index queries[i]-1
is 1, means we will toggle OFF the switch and decrease the value of number_of_switches
by 1. number_of_swiches -= 1;
now we will call the function on(number_of_on, number_of_switches)
and if the value return is 1
and the current
was 0
means the bulb must have changed its state (from 0 -> 1). SO count += 1
if the value at element at index queries[i]-1
is 0, means we will toggle ON the switch and increase the value of number_of_switches
by 1. number_of_swiches += 1;
now we will call the function on(number_of_on, number_of_switches)
and if the value return is 0
and the current
was 1
means the bulb must have changed it state (from 1 -> 0). So count += 1
.
I tested your code. I found one logical error in the method I mention below.
static boolean on(int arr[])
{
int sum = 0;
for(int i = 0;i < arr.length;i++) sum+=arr[i];
//The test expression should be sum >= arr.length/2.0
if(sum > arr.length/2.0) return true;
else return false;
You said in the problem statement:
So the bulb will be in the "on" state only when half or more than half of the given n of switches to be "on".
To test this condition the test expression should be
if (sum >= arr.length/2.0)
and not
if (sum > arr.length/2.0)
Another improvement in your code is its time complexity
. Currently you are checking the state of the bulb by checking all the switches.
There are n
number of bulbs and q
number of queries . If you check the state of the bulb in this manner it will result in O(q*n)
.
It can be done in O(q + n)
.
If you declare a variable to store the total number of switches on and update it after each query. Then use this variable to check if there is a change in the state of the bulb, your code will be more efficient.
I have provided a code below using this implementation.
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
int testCases = Integer.parseInt(bufferedReader.readLine().trim());
//To score output of all the testCases
int[] result = new int[testCases];
for (int i = 0;i < testCases;i++)
{
//number of bulbs
int n = Integer.parseInt(bufferedReader.readLine().trim());
//input in String array
String[] in = bufferedReader.readLine().split(" ");
//To count how many switches are in on state
int countOn = 0;
//To store if the bulb is currently on or not
boolean isBulbOn;
//Converting the input String array to number array
int[] bulbState = new int[n];
for(int j = 0;j < n;j++)
{
int x = Integer.parseInt(in[j]);
bulbState[j] = x;
if (x == 1) countOn++;
}
//Initializing isBulbOn to true if countOn >= n/2
//Math.ceil() conversion is necessary since in case of odd number of bulbs n/2 will result in 1
//and isBulbOn condition will be assigned an incorrect value
//Here 2.0 is necessary since if it just to n/2 will result in integer not a double
isBulbOn = countOn >= (int)Math.ceil(n/2.0);
//Input number of queries and store it
int q = Integer.parseInt(bufferedReader.readLine().trim());
String[] toggleInput = bufferedReader.readLine().trim().split(" ");
//To count number of times the state has changed
int countStateChange = 0;
for (int j = 0;j < q;j++)
{
int currentToggle = Integer.parseInt(toggleInput[j]);
//If switch is on make it off else do the opposite
if(bulbState[currentToggle-1] == 0)
{
bulbState[currentToggle-1] = 1;
countOn++;
}
else
{
bulbState[currentToggle-1] = 0;
countOn--;
}
//Check if bulb was previously on and the switch on is less than half of n
//Register a state change
if (isBulbOn && countOn < (int)Math.ceil(n/2.0))
{
isBulbOn = false;
countStateChange++;
}
//Check if bulb was previously off and the switch on is more than or equal to half of n
//Register a state change
if (!isBulbOn && countOn >= (int)Math.ceil(n/2.0))
{
isBulbOn = true;
countStateChange++;
}
}
//store the result of current test case
result[i] = countStateChange;
}
//Print all the results
for (int x: result)
System.out.println(x);
}
I hope I have helped you. I did test my code against various inputs. Do comment if you find any problems or if any part of my code is hard to understand.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.