# L R Answer - --- ---- ------ 0 1 10 1: This is when a=1 and b=10. 1 1 99 2: There are many pairs with similarity 2, for example (23,32) and (38,83). 2 99 100 0: There is only one pair (99, 100). It's similarity is zero. 3 1000 1010 2 4 444 454 2
Below, I show you the skeleton, how it compiles and how it runs. First, here's Similars.cpp:
#include <string> #include <vector> #include <map> #include <iostream> #include <cstdio> #include <cstdlib> using namespace std; class Similars { public: string Print_Sets; string Print_Similarities; int maxsim(int L, int R); }; int Similars::maxsim(int L, int R) { printf("L = %d. R = %d.\n", L, R); if (Print_Sets == "y") printf("Print_Sets was set.\n"); if (Print_Similarities == "y") printf("Print_Similarities was set.\n"); return 0; } |
And here's how to compile and run:
UNIX> g++ main.cpp UNIX> ./a.out usage: ./a.out L R print-sets(y|n) print-similarities(y|n) UNIX> ./a.out 1 10 n n L = 1. R = 10. 0 UNIX> ./a.out 20 30 y n L = 20. R = 30. Print_Sets was set. 0 UNIX> ./a.out 44 55 n y L = 44. R = 55. Print_Similarities was set. 0 UNIX>Instead of giving my program the example number, like you usually do, you give it L, R, and two y|n arguments, which specify whether to print the sets and similarities. I'll tell you what "sets" and "similarities" are below. If you say "y" to the first of these, it sets the variable Print_Sets to "y", and my program prints the sets. If you say "y" to the second of these, it sets the variable Print_Similarities to "y", and my program prints the similarities. You don't have to use Print_Sets or Print_Similarities, but you'll need to define them to make them work with main.cpp. The nice thing about using them is that you can debug with them, and your programs will still work when you submit them to Topcoder (since Topcoder won't set them to "y" -- they will just be empty strings.
The similarity of 15,225 and 52,110 is three:
Now, how many potential digit sets are there? That's the same as asking, "How big is the power set of {0,1,2,3,4,5,6,7,8,9}?" That's 210 = 1024. That's a very nice and manageably small number.
The best way to represent a small set like this is in binary. If digit i is set in a number, than its set will have the bit (1 << i) set to one. For example:
Set | Binary | Hex |
{1} | 0000000010 | 0x2 |
{1,2,3} | 0000001110 | 0xe |
{1,5} | 0000100010 | 0x22 |
{1,2,5} | 0000100110 | 0x26 |
{0,1,2,5} | 0000100111 | 0x27 |
UNIX> ./a.out 1 2 y n i = 1. Set = 0x002. Occurrences = 1 i = 2. Set = 0x004. Occurrences = 1 0 UNIX> ./a.out 123 129 y n i = 123. Set = 0x00e. Occurrences = 1 i = 124. Set = 0x016. Occurrences = 1 i = 125. Set = 0x026. Occurrences = 1 i = 126. Set = 0x046. Occurrences = 1 i = 127. Set = 0x086. Occurrences = 1 i = 128. Set = 0x106. Occurrences = 1 i = 129. Set = 0x206. Occurrences = 1 2 UNIX> ./a.out 11115 11116 y n i = 11115. Set = 0x022. Occurrences = 1 i = 11116. Set = 0x042. Occurrences = 1 1 UNIX> ./a.out 11155 11156 y n i = 11155. Set = 0x022. Occurrences = 1 i = 11156. Set = 0x062. Occurrences = 1 2 UNIX> ./a.out 52110 52111 y n i = 52110. Set = 0x027. Occurrences = 1 i = 52111. Set = 0x026. Occurrences = 1 3 UNIX>
UNIX> ./a.out 1 11 y n i = 1. Set = 0x002. Occurrences = 1 i = 2. Set = 0x004. Occurrences = 1 i = 3. Set = 0x008. Occurrences = 1 i = 4. Set = 0x010. Occurrences = 1 i = 5. Set = 0x020. Occurrences = 1 i = 6. Set = 0x040. Occurrences = 1 i = 7. Set = 0x080. Occurrences = 1 i = 8. Set = 0x100. Occurrences = 1 i = 9. Set = 0x200. Occurrences = 1 i = 10. Set = 0x003. Occurrences = 1 i = 11. Set = 0x002. Occurrences = 2 1 UNIX> ./a.out 1231 1233 y n i = 1231. Set = 0x00e. Occurrences = 1 i = 1232. Set = 0x00e. Occurrences = 2 i = 1233. Set = 0x00e. Occurrences = 3 3 UNIX>
This is a nested for loop with iterators. I had the first iterator go from begin() to end(). Then, if the element to which the iterator pointed had only one occurrence, I had a second iterator that started one past the first iterator stopped when it got to end(). I recorded the maximum similarity of all of iterators with the first. If the first iterator's element had two or more occurrences, then I simply calculated its similarity with itself.
Go ahead and write these loops and print out the set ids, and their intersections (which is simply the bitwise AND operator (&)). Compare them with my program, and for now, ignore the "similarities". Just make sure your loop is printing out the right S1's and S2's, and the right intersections, first when all of the occurrences are one.
UNIX> ./a.out 1 4 y y i = 1. Set = 0x002. Occurrences = 1 i = 2. Set = 0x004. Occurrences = 1 i = 3. Set = 0x008. Occurrences = 1 i = 4. Set = 0x010. Occurrences = 1 S1: 0x002 S2: 0x004 S1&S2: 0x000 Similarity: 0 S1: 0x002 S2: 0x008 S1&S2: 0x000 Similarity: 0 S1: 0x002 S2: 0x010 S1&S2: 0x000 Similarity: 0 S1: 0x004 S2: 0x008 S1&S2: 0x000 Similarity: 0 S1: 0x004 S2: 0x010 S1&S2: 0x000 Similarity: 0 S1: 0x008 S2: 0x010 S1&S2: 0x000 Similarity: 0 0 UNIX> ./a.out 9871 9874 y y i = 9871. Set = 0x382. Occurrences = 1 i = 9872. Set = 0x384. Occurrences = 1 i = 9873. Set = 0x388. Occurrences = 1 i = 9874. Set = 0x390. Occurrences = 1 S1: 0x382 S2: 0x384 S1&S2: 0x380 Similarity: 3 S1: 0x382 S2: 0x388 S1&S2: 0x380 Similarity: 3 S1: 0x382 S2: 0x390 S1&S2: 0x380 Similarity: 3 S1: 0x384 S2: 0x388 S1&S2: 0x380 Similarity: 3 S1: 0x384 S2: 0x390 S1&S2: 0x380 Similarity: 3 S1: 0x388 S2: 0x390 S1&S2: 0x380 Similarity: 3 3 UNIX>And next when you have multiple occurrences of the same set:
UNIX> ./a.out 1231 1233 y y i = 1231. Set = 0x00e. Occurrences = 1 i = 1232. Set = 0x00e. Occurrences = 2 i = 1233. Set = 0x00e. Occurrences = 3 S1: 0x00e S2: 0x00e S1&S2: 0x00e Similarity: 3 3 UNIX>