PROBLEM LINK :
Contest
Practice
Author : Asim Krishna Prasad
Tester : Sarvesh Mahajan
DIFFICULTY :
CAKEWALK
PREREQUISITES :
Bitwise operations
PROBLEM :
Given two sets of strings A and B, you have to find how many such pairs (Ai, Bj) exist such that concatenation of the two strings contains all the letters of English alphabet.
EXPLANATION :
First there are a few observations :
- We don't need the whole string for computation. We just need to know if a particular alphabet is present in a particular string or not.
- Since we can loop over A x B, we only need a fast method to represent and concatenate two representations of strings
To solve this problem we can use bits to map if a particular alphabet is present in a string or not. So,
- A string will be represented as an integer value which has bits set corresponding to each distinct alphabet present in the string. Example : for string A : 1, for string AC : 5 = (101)2.
- Now concatenation of two strings would be equivalent to taking bitwise-or of the corresponding integers. That is, if either one of the strings has a bit set, it would be set in the concatenated string.
To make the integer corresponding to a string :
int inLimit = strlen(str1);
int num = 0;
fl(j,0,inLimit)
{
int ele = int(str1[j]-'A');
num |= (1 << ele);
}
Now the answer is the number of pairs (Ai Bj) such that bitwise-or of them has 26 set bits from beginning or bitwise-or has value equal to ( (1 << 26) - 1).
SOLUTION :
Setter’s solution
I think it the TL was a little strict and could be relaxed. I had a lot of trouble getting it AC even with expected approach.
@nibnalin Can you please link me your code which gave TLE?
1 Like
@pakhandi Sure, https://www.codechef.com/viewsolution/11623052
This gets TLE even though I have used scanf+printf. Adding few constant time optimisations made the same accepted: https://www.codechef.com/viewsolution/11623490
You are using strlen() in the loop… which makes your solution a little slower…
@pakhandi, yeah, probably, but compilers usually optimise that if we use -O2 flag(CC does). The AC submission also used strlen and compiler optimised versions are expected to be the same afaik.
Hey, I really don’t know if compiler optimizes this. I tried running your code and it runs forever on my system too. Since you are using strlen() call for every iteration, this makes your loop of order of n^2 which effectively makes that complete loop : n1 * strlen(S1) * strlen(S1)
While in the AC code you have saved the strlen() result in a variable and used it which makes it : n1 * strlen(S1)
Are you sure you used optimisation flags? I tried to look up the machine code, it seems optimised with -O2 flag on my machine(G++ 4.9)
Yep, it looks like -O2 is supposed to optimise it https://godbolt.org/g/DGeWpD
Anyway, thanks for your help. I suppose there is some reason due to which it isn’t optimising the way it should. I
ll be more careful next time