Note to potential future reviewers: This code appears to be suitable for Python 3 only.
Let's structure your code a little and see if we can fix the timing problem.
I propose the following order:
- Global variables
- Helper functions
- Main function
- Input
- Actual calculations
if __name__ == '__main__':
The latter may not look familiar to you, but it's an include guard. It's a good practice to start using those, especially if you ever want to re-use parts of your code. Now your main
only gets executed if the script is called directly, not when it's called by import
.
Which leaves us after the first couple of edits with the following:
x = []
y = []
def ask_amount():
return int(input())
def ask_lines(amount):
for i in range(amount):
l = list(map(int, input().split()))
x.append(l[0])
y.append(l[1])
def ask_queries(amount):
return list(map(int, input().split()))
def main():
ask_lines(ask_amount())
q = ask_amount()
for i in range(q):
p = ask_queries(q)
L = p[0]-1
R = p[1]-1
X = p[2]
Y = p[3]
flag = 0
for i in range(L, R+1, 1):
if(Y - x[i]*X - y[i] < 0):
print("YES")
flag = 1
break
if(flag == 0):
print("NO")
if __name__ == '__main__':
main()
Which still isn't much, but the structure is getting better. Note that I made your comma's breath ((L,R+1,1)
is more readable when written as (L, R+1, 1)
and there's no longer a ;
behind your break
. It's Python, we don't need semi-colons after break
/continue
etc.
One of the major things fixed now is your code was executing before you finished reading your input. That's usually a bad idea unless you're in some kind of do until told otherwise
loop, which this wasn't. Now it waits for all input before it executes the rest.
I/O used to be:
2
-1 3
-2 -4
3
1 2 0 0
YES
1 1 0 0
YES
2 2 0 0
NO
Now it is:
2
-1 3
-2 -4
3
1 2 0 0
1 1 0 0
2 2 0 0
YES
YES
NO
There's still a couple of problems with it. We're now iterating an extra time, which can't be helpful for the time it takes to execute. But at least it looks better now, so we can see what we're doing. It still fails just as many test cases as your original code did, so at least we didn't do noticeably worse.
What else can we do better?
L = query[0]-1
R = query[1]-1
X = query[2]
Y = query[3]
flag = 0
for i in range(L, R+1, 1):
R
= some value minus one. The actual value we need is R
plus one. Since the description of the challenge says L
and R
are given (not L+1
and R+1
), it doesn't make sense to modify them.
Let's go from L-1
to R
instead.
L = query[0]
R = query[1]
X = query[2]
Y = query[3]
flag = 0
for i in range(L-1, R, 1):
Another thing we don't need is this entire flag
business. Let's use return
values instead:
x = []
y = []
def ask_amount():
return int(input())
def ask_lines(amount):
for i in range(amount):
l = list(map(int, input().split()))
x.append(l[0])
y.append(l[1])
def ask_queries(amount):
return list(map(int, input().split()))
def does_line_exist(query):
L = query[0]
R = query[1]
X = query[2]
Y = query[3]
for i in range(L-1, R, 1):
if(Y - x[i]*X - y[i] < 0):
return True
return False
def main():
ask_lines(ask_amount())
q = ask_amount()
queries = []
for i in range(q):
queries.append(ask_queries(q))
for query in queries:
if does_line_exist(query):
print("YES")
else:
print("NO")
if __name__ == '__main__':
main()
Poof! No more flag
.
But wait, this still doesn't solve your TLE problem! No, I'm afraid not and I'm going to tell you why. The author of the problem has made the constraints so narrow that the only acceptable solutions are those which use the Convex hull trick. It basically boils down to checking whether a value is < -y
instead of < 0
.
I'll leave the actual implementation of said trick to you. Feel free to post a follow-up question once you've implemented it.