I'm practicing for ACM ICPC and I came on this problem from 2017 ACM ICPC Arab Regionals:
First, let’s define an undirected connected labeled graph, it’s a graph with N nodes with a unique label
for each node and some edges, there’s no specific direction for each edge, also duplicate edges and edges
from a node to itself aren’t allowed, and from any node you can reach any other node.
A bridge in such graph is an edge that if we remove it, the graph will be disconnected (there will
exist nodes which aren’t reachable from each other).
In this problem you are given N and K, and your task is to count the number of different undirected
connected labeled graphs with exactly N nodes and K bridges. Since that number can be huge, print
it modulo M.
An edge is defined using the labels of the nodes it connects, for example we can say (X, Y ) is an
edge between X and Y , also (Y, X) is considered the same edge (since it’s undirected). Two graphs are
considered different, if there’s an edge which exists in one of them but not the other.
Input:
Your program will be tested on one or more test cases. The first line of the input will be a single integer
T (1 ≤ T ≤ 100) representing the number of test cases. Followed by T test cases.
Each test case will be just one line containing 3 integers separated by a space, N (1 ≤ N ≤ 50), K
(0 ≤ K < N) and M (1 ≤ M ≤ 10^9), which are the numbers described in the statement. It’s guaranteed that N will not be more than 25 in 95% of the test cases
Output:
For each test case, print a single line with the number of graphs as described above modulo M.
Sample Input:
4
3 2 10
3 0 10
6 3 10000
6 3 1000
Sample Output
3
1
2160
160
I tried to come up with some formula that would work for all N and K but I had no success. Can someone tell me what should I do to solve it, because I couldn't find any editorial? Thanks in advance
Related
Given a list of N intervals [a,b] cost c, find the minimum sum of 2 non-overlapping intervals. I have an algorithm in O(n^2) ( pastebin.com/kveAZTwv ) but i don t find the O(N log N).
The first value is the number of intervals. the other lines are : a,b,c where a is the beginning of the interval, b the end and c the cost.
example :
input :
3
0 10 1
1 2 2
9 12 2
output :
4
Here is the basic idea for an algorithm in O(n log n), I am sure it can be done more efficiently:
1) sort all intervals accoring to their endpoint, each endpoint is a potential splitpoint where intervals to the right and intervals to the left do not overlap
2) now scan through the sorted intervals and for each spiltpoint remember the minimum cost interval to the left.
3) sort all elements according to their startpoint
4) for each splitpoint memorize additionally the minimum cost interval to the right(having its startpoint after the splitpoint). This is also possible with a single scan from back to front of the sorted elements
5) for each splitpoint add the two corresponding cost and look for the minimum.
Sorry this is a bit informal since i am on mobile.
I recently came across an interesting problem:
Given two lists of intervals, find the total number of overlapping intervals from the two lists.
Example
L1: ([1,2][2,3][4,5][6,7])
L2: ([1,5][2,3][4,7][5,7])
[1,5] overlaps [1,2] [2,3] [4,5]
[2,3] overlaps [1,2] [2,3]
[4,7] overlaps [4,5] [6,7]
[5,7] overlaps [4,5] [6,7]
total = 3+2+2+2 = 9
Obviously the brute force approach works, but it's too slow (I need something better than O(n^2)).
I also fond a similar problem here. But it's not exactly the same...
Any help is appreciated
Make two sorted lists with pairs (value; +1 or -1 for start and end of interval).
Two counters - Count1 and Count2 which show number of active intervals in the first and the second lists.
Walk through both lists in merge manner.
When you get pair from the first list with +1 - increment Count1
When you get pair from the first list with -1 - decrement Count1 and add Count2 to the result
The same for pairs from the second list
Pseudocode for the last stage
CntA = 0
CntB = 0
Res = 0
ia = 0
ib = 0
while (ia < A.Length) and (ib < B.Length)
if Compare(A[ia], B[ib]) <= 0
CntA = CntA + A[ia].Flag
if (A[ia].Flag < 0)
Res = Res + CntB
ia++
else
CntB = CntB + B[ib].Flag
if B[ib].Flag < 0
Res = Res + CntA
ib++
Subtle moment - comparison if Compare(A[ia], B[ib]) <= 0
We should here take into account also flags - to correctly treat situations when endpoints only touch like [1..2][2..3] (you consider this situation as intersection). So both sorting and merge comparator should take synthetic value like this: 3 * A[ia].Value - A[ia].Flag. With such comparing start of interval is treated before end of interval with the same coordinate.
P.S. Made quick test in Delphi. Works for given data set and pair of others.
Delphi code (ideone FPC doesn't compile it due to generics)
Try to look for sweep line algorithms, it will give you the fastest solution.
You can check short description at TopCoder site or watch video from Robert Sedgwick. These describe a bit more hard problem but should give you an approach how to solve yours.
Actually the main idea is to walk over sorted list of begins and ends of your segments each time updating the lists of segments in the special intersecting list.
For this task you will have two intersections lists for each original list respectively. At the start both intersection lists are empty. On coming over begin of the segment you add it to the appropriate intersection list and it obviously intersects all the segments in the other intersection list. When coming to an end of the segment just remove it from the intersection list.
This algorithm will give you O(n log(n)) speed and in worst case O(n) memory.
You may be able to use std::set_intersection in a loop over the second array to match it with each item in the first array. But I am not sure if the performance will match your requirements.
I recently stumbled upon the Interval Tree ADT when tackling a similar question - I suspect it'll be useful for you, whether you implement it or not.
It is basically a ternary tree, and I built it with nodes containing:
Left sub-tree containing intervals less than current node
Right sub-tree containing intervals more than current node
List of overlapping intervals
Interval value encompassing all overlapping intervals
After building the tree in O(n*log(n)), a query function - to check overlapping intervals - should be O(log(n) + m) where m is the number of overlapping intervals reported.
Note that on creation, sorting by end value in the interval and splitting the list should help keep things balanced.
With given N lists of M numbers in each list we have to find ONE element from each group such
every pair ai aj gives |ai-aj| as small as possible.
For example
we have 3 lists
{12,16,67,43}
{7,17,68,48}
{14,15,77,54}
And to minimize result we have to pick
number 16 from list 1
number 17 from list 2
number 15 from list 3
so
|16-17|=1
|16-15|=1
|17-15|=2
so our result is :2
How to solve it fastly? in N*M time ? or log something time
Chris
If you use a linear search, the complexity is O(N*M) for one match (i.e., for each element in set j, do a linear search for the most similar item from set i, and pick the smallest of those results.
If you sort each set first, you get to (at least) O(N log N)+O(M log M) for the sort, and O(M log N) for the searches (where N is the number of elements in set i, and M the number of elements in set j). If you walk through the two sets together you can probably reduce that to O(N + M) for the combined search.
An emirp (prime spelled backwards) is a pime number whose reversal is also prime. Ex. 17 & 71. I have to write a program that displays the first 100 emirps. It has to display 10 numbers per line and align the numbers properly:
2 3 5 7 11 13 17 31 37 71
73 79 97 101 107 113 131 149 151 157.
I have no cue what I am doing and would love if anyone could dump this down for me.
It sounds like there are two general problems:
Finding the emirps.
Formatting the output as required.
Break down your tasks into smaller parts, and then you'll be able to see more clearly how to get the whole task done.
To find the emirps, first write some helper functions:
is_prime() to determine whether a number is prime or not
reverse_digits() to reverse the digits of any number
Combining these two functions, you can imagine a loop that finds all the numbers that are primes both forward and reversed. Your first task is complete when you can simply generate a list of those numbers, printing them to the console one per line.
Next, work out what format you want to use (it looks like a fixed format of some number of character spaces per number is what you need). You know that you have 100 numbers, 10 per line, so working out how to format the numbers should be straightforward.
Break the problem down into simpler sub-problems:
Firstly, you need to check whether a number is prime. This is such a common task that you can easily Google it - or try a naive implementation yourself, which may be better given that this is homework.
Secondly, you need to reverse the digits of a number. I'd suggest you figure out an algorithm for this on a piece of paper first, then implement it in code.
Put the two together - it shouldn't be that hard.
Format the results properly. Printing 10 numbers per line is something you should be able to figure out easily once the rest is done.
Once you have a simple version working you might be able to optimise it in some way.
A straight forward way of checking if a number is prime is by trying all known primes less than it and seeing if it divides evenly into that number.
Example: To find the first couple of primes
Start off with the number 2, it is prime because the only divisors are itself and 1, meaning the only way to multiple two numbers to get 2 is 2 x 1. Likewise for 3.
So that starts us off with two known primes 2 and 3. To check the next number we can check if 4 modulo 2 equals 0. This means when divide 2 into 4 there is no remainder, which means 2 is a factor of 4. Specifically we know 2 x 2 = 4. Thus 4 is not prime.
Moving on to the next number: 5. To check five we try 5 modulo 2 and 5 modulo 3, both of which equals one. So 5 is prime, add it to our list of known primes and then continue on checking the next number. This rather tedious process is great for a computer.
So on and so forth - check the next number by looping through all previous found primes and check if they divide evenly, if all previously found primes don't divide evenly, you have a new prime. Repeat.
You can speed this up by counting by 2's, since all even numbers are divisible by two. Also, another nice trick is you don't have to check any primes greater than the square root of the number, since anything larger would need a smaller prime factor. Cuts your loops in half.
So that is your algorithm to generate a large list of primes.
Collect a good chunk of them in an array, say the first 10,000 or so. And then loop through them, reverse the numbers and see if the result is in your array. If so you have a emirp, continue until you get the first 100 emirps
If the first 10,000 primes don't return 100 emirps. Move on to the next 10,000. Repeat.
For homework, I would use a fairly simplistic isPrime function, pseudo-code along the lines of:
def isPrime (num):
set testDiv1 to 2
while testDiv1 multiplied by testDiv1 is less than or equal to num:
testDiv2 = integer part of (num divided by testDiv1)
if testDiv1 multiplied by testDiv2 is equal to num:
return true
Add 1 to testDiv1
return false
This basically checks whether the number is evenly divisible by any number between 2 and the square root of the number, a primitive primality check. The reson you stop at the square root is because you would have already found a match below it if there was one above it.
For example 100 is 2 times 50, 4 times 25, 5 time 20 and 10 times 10. The next one after that would be 20 times 5 but you don't need to check 20 since it would have been found when you checked 5. Any positive number can be expressed as a product of two other positive numbers, one below the square root and one above (other than the exact square root case of course).
The next tricky bit is the reversal of digits. C has some nice features which will make this easier for you, the pseudo-code is basically:
def reverseDigits (num):
set newNum to zero
while num is not equal to zero:
multiply newnum by ten
add (num modulo ten) to newnum
set num to the integer part of (num divided by ten)
return newNum
In C, you can use int() for integer parts and % for the modulo operator (what's left over when you divide something by something else - like 47 % 10 is 7, 9 % 4 is 1, 1000 % 10 is 0 and so on).
The isEmirp will be a fairly simplistic:
def isEmirp (num):
if not isPrime (num):
return false
num2 = reverseDigits (num)
if not isPrime (num2):
return false
return true
Then at the top level, your code will look something like:
def mainProg:
create array of twenty emirps
set currEmirp to zero
set tryNum to two
while currEmirp is less than twenty
if isEmirp (tryNum):
put tryNum into emirps array at position currEmirp
add 1 to currEmirp
for currEmirp ranging from 0 to 9:
print formatted emirps array at position currEmirp
print new line
for currEmirp ranging from 10 to 19:
print formatted emirps array at position currEmirp
print new line
Right, you should be able to get some usable code out of that, I hope. If you have any questions of the translation, leave a comment and I'll provide pointers for you, rather than solving it or doing the actual work.
You'll learn a great deal more if you try yourself, even if you have a lot of trouble initially.
Buttons
Each cell of an N x N grid is either a 0 or a 1. You are given two such N x N grids, the initial grid and the final grid. There is a button against each row and each column of the initial N x N grid. Pressing a row-button toggles the values of all the cells in that row, and pressing a column-button toggles the values of all the cells in that column.
You are required to find the minimum number of button presses required to transform the grid from the initial configuration to the final configuration, and the buttons that must be pressed in order to make this transformation.
When the initial and the final configurations are the same, print "0".
Input
The first line contains t, the number of test cases (about 10). Then t test cases follow.
Each test case has the following form:
The first line contains n, the size of the board (1 ≤ n ≤ 1000).
n lines follow. The ith line contains n space separated integers representing the ith row of the initial grid. Each integer is either a 0 or a 1.
n lines follow, representing the final grid, in the same format as above.
Output
For each test case, output the number of row-button presses, followed by the row buttons that must be pressed. Print the number of column-button presses next, followed by 0-indexed indices of the column buttons that must be pressed. The total number of button presses must be minimized.
Output "-1" if it is impossible to achieve the final configuration from the initial configuration. If there is more than one solution, print any one of them.
Input:
1
3
0 0 0
1 1 0
1 1 0
1 1 0
1 1 1
1 1 1
Output:
1
0
1
2
Though it works absolutely fine on my machine,it doesnt accept a solution at codechef and gives me a wrong answer.Can anyone guide me what to do pls pls pls??
Code has been written in C++ and compiled using g++ compiler.
In the code posted, I would revise the code after you calculate "matrixc". I find it very difficult to follow beyond that point, so I'm going to stop looking at the code and talk about the problem. For those without the code, matrix C = initial matrix - final matrix. The matrices are over the binary field.
In problems like these, look at the symmetries in the solution. There are three symmetries. One is the order of the buttons does not matter. If you take a valid solution and rearrange it, you get another valid solution. Another symmetry is that pressing a button twice is the same as not pressing it at all. The last symmetry is that if you take the complement of a valid solution, you get another valid solution. For example, in a 3x3 grid, if S = { row1, row3, col1 } is a solution, then S' = { row2, col2, col3 } is also a solution.
So all you need to do is find one solution, then exploit the symmetry. Since you only need to find one, just do the easiest thing you can think of. I would just look at column 1 and row 1 to construct the solution, then check the solution against the whole matrix. If this solution gives you more than N buttons to press for an NxN grid, then take the solution's complement and you'll end up with a smaller one.
Symmetry is a very important concept in computer science and it comes up almost everywhere. Understanding the symmetries of this problem is what allows you to solve it without checking every possible solution.
P.S. You say this code is C++, but it is also perfectly valid C if you remove #include <iostream> from the top. It might take a lot less time to compile if you compile it as C.