320 likes | 470 Views
Suggested Solutions of Sharif Internet Contest 09. Aideen NasiriShargh (aideen.ir) 11/5/2009. Problem A: AmaTeuR HaCKeRS !. NO SIGNAL. You ARe HaCKeD!. You ARe SiBiLiZeD!. Should I tell the rest?!. YES SIGNAL.
E N D
Suggested Solutions ofSharif Internet Contest 09 Aideen NasiriShargh (aideen.ir) 11/5/2009
NO SIGNAL You ARe HaCKeD! You ARe SiBiLiZeD! Should I tell the rest?! YES SIGNAL
Problem A: AmaTeuRHaCKeRS! • Author: Aideen NasiriShargh • Solution & TestData: Aideen NasiriShargh • Task: Count number of HaCKeRiSH words in a line! • 117 out of 135 teams submitted. 57 teams got AC. • Using stringstream, one could get away from all end-line (CR-LF) problems. • Although it was a Task-A problem, STL (in C++) could come to help.
Problem A (cont’d) bool ishacker(const string &s) { if (!isupper(s[0])) return false; FRI(it,s) { if (it == s.begin()) continue; bool vowel = (string("aeiou").find(tolower(*it)) != string::npos); if (vowel ^ (bool)islower(*it)) return false; } return true; } #define FOR(i,x,n) for (__typeof(x) i = (x); i != (n); i++) #define FR(i,n) FOR(i,0,n) #define FRI(it,v) FOR(it,v.begin(),v.end())
Problem A (cont’d) For each testcase{ int n = 0, good = 0; getline(cin, s); stringstreamss(s); while (ss >> w) { n++; good += ishacker(w); } printf("%d out of %d.\n", good, n); }
Problem B: Bahman’s Disapproval! • Author: Aideen NasiriShargh • Solution & TestData: Aideen NasiriShargh • Task: Count number of prime numbers in a range of 100K numbers. • 98 out of 135 teams submitted. 44 teams got AC. • Important Points: • Range was fixed [88’200K, 88’201K), each one’s prime-ity can be calculated in O(√n) but • Number of Tests (1 ≤ T ≤ 100) could cause redundancy!
Problem B (con’td) • Solution: • Calculate isPrime[x] for all x’s in the range once and store it later. • Optional Improvement (you could get AC w/o this one) • Store all prime numbers in a sorted-array and answer each query in O(lg K) where K is number of primes in the range (near 5% of 100K).
Problem B (con’td) const int Base = 88100000; const int MAX_W = 199999; bool prime[MAX_W+3]; bool isprime(int x) { if (x == 2) return true; if (x <= 1 || x % 2 == 0) return false; for (int i = 3; i * i <= x; i += 2) if (x % i == 0) return false; return true; }
Problem B (con’td) int main() { int testn; cin >> testn; FR(i,MAX_W+1) prime[i] = isprime(Base+i); FR(testi,testn) { int a, b; cin >> a >> b; int ans = 0; FOR(i,a,b+1) ans += prime[i-Base]; //isprime(i); double p = 100 * double(ans) / (b-a+1); printf("%0.0lf%%\n", p); } return 0; }
Problem C: Captivity Of Casuality! • Author: SaeedReza Seddighin • Solution & TestData: SaeedReza Seddighin • Task: Given some “X because Y”, you should answer “Why Z?”. Causes are transitive. • 40 out of 135 teams submitted. 25 teams got AC. • Solution: • Separate sentences by “because” to get X and Y. • Add this clue as a directed edge from Y to X. • For each question, follow the path from Z as long as you can.
Problem C: Captivity Of Casuality! • Idea: Use STL! • map<string,string> C; // The graph as a map • Set<string> S; // To store current X’s while (S.find(x) == S.end()) if (C.find(x) == C.end()) break; else { S.insert(x); x=Map[x];} if (Set.find(x) == Set.end()) cout<<"Because "<<x<<'.'<<endl; else cout<<"Too complicated."<<endl;
Problem D: Dr. B! • Author: SaeedReza Seddighin • Solution & TestData: SaeedReza Seddighin • Task: Let Dr. B apply his fans! • 4 out of 135 teams submitted. 2 teams got AC. • Important Points: • The main idea for solving this problem is a full search. • we should test all possible combinations of classes that could be our result, and choose the one which has most difference with initial ones.
Problem D: Dr. B! (cont’d) • How? • First we should generate all possible combinations ( which are C(m,n) ). • Backtracking is an efficient way for generating but there are some other simpler ways that coder may use. • After that we should check whether a combination a valid or not, validity means that Dr. B could make that combination using his rules. Now the problem is what a valid combination is. • It is obvious that classes of a valid combination should be independent to each other. In the other hand no two classes should share a period of time. • Second condition is that there should be a way to add/remove classes that changes initial combination of classes into it.
Problem D: Dr. B! (cont’d) • Condition 1) Classes of a valid combination should be independent to each other. In the other hand no two classes should share a period of time. • Testing the first condition could be easilty done in o(n*n) time. • Condition 2) There should be a way to add/remove classes that changes initial combination of classes into it. • For testing the second condition we can consider all m! ways of inserting new classes. it is a tricky point that a way of inserting classes is valid (could be done using rules) iff after inserting ith class at least i classes of initial combination should have conflict with new ones.!
Problem E: Ehem, Ehem, NBL! • Author & Solution: SaeedReza Seddighin • TestData: Aideen NasiriShargh • Task: We know one person is either Lucky or Unlucky. A team is a group of 3 persons. A team is Winner iff all 3 persons in that team be Lucky. • 17 out of 135 teams submitted. 11 teams got AC. • Is it the famous NP-complete problem of 3-SAT? • No! 3Sat is (A OR B OR C) AND (X OR Y OR Z) • But, here we have (A AND B AND C)!
Problem E: Ehem, Ehem, NBL! • Solution: • Consider all winner teams, all members of those teams MUST BE lucky. (isn’t it?) • Set their luck==true. • Now, after the previous step, consider the rest (losers team). Is there any team among them, which has 3 members with who are luck==true? • If so, it’s an inconsistency. • Otherwise, you can call persons with unset luck, unlucky!
Problem E (cont’d) • How to find the state of the new team? • Easy! Assume it is lucky, run the inconsistency test once again (now in n+1 teams). Any contradiction means the new team is loser. • Otherwise, the new team can be winner!
Problem E (cont’d) bool solve (int n) {// is first n teams consistent? set<int> lucky; FR(i,n) if (a[i].gold) // winners FR(j,3) lucky.insert(a[i].mem[j]); FR(i,n) if (!a[i].gold) { // losers FR(j,3) if (!isin(lucky, a[i].mem[j])) goto hell; return false; // a loser with 3 not-goto-ed men hell: ; // check next loser team } return true; }
Problem E (cont’d) if (!solve(n)) cout << "Inconsistent data!" << endl; else if (!solve(n+1)) cout << "No, they are natural-born-losers!" << endl; else cout << "Yes, they can win!" << endl;
Problem F: Factorialz Again! • TestData & Solution: Mahdi SafarNejad • Task: Find number of trailing zeros (in right end) of n! in base K. • 53 out of 135 teams submitted. 23 teams got AC. • It’s about math again! • Random tests causes some incorrect codes get AC. :-(
Problem F: Factorialz Again! • The Sieve of Eratosthenes is a simple algorithm for finding all prime numbers up to a specified integer. (from wikipedia)
Problem F: Factorialz Again! • Solution: • For each prime number P, find maximum k that: n % (P^k) == 0 • How do you do that? • Answer is minimum of such k’s for all Ps. • Incorrect solution: • Do that only for largest available P, not all Ps. As you work on powers of 5 when base is 10.
Problem G: Glamorous Polygons! • Author, Testdata, Solutions: Sepideh MahAbadi • Eased Solution: Aideen NasiriShargh • Task: Given 2 Polygon, tell whether they are similar in shape or not? • 9 out of 135 teams submitted. 2 teams got AC. • N can be as large as 100’000. So O(N^2) algorithm does not work!
Problem G: Glamorous Polygons! • Solution: • Two polygons are similar if: • 1) Their angels be the same in order. (is it enough)? • Imagine Rectangle and Square! • 2) Length of their edges have the same ratio. (is it enough)? • Image lozenge and Square! • Both of the above conditions must be held. Why is it enough now?
Problem G: Glamorous Polygons! • Solution: • Calculate pair<side-length, angel> for both of the polygons and store them in two arrays. • Now you want to find other whether one can become like the other by shifting and multiplying the lengths in an arbitrary factor? • How can you do that in O(N)? • duplicate the first array and append the copy to it’s end. i.e. ABC => ABCABC • Now find the second array (size N) in the first array (which is now 2N in size). Use that by KMP algorithmin O(N + 2N) = O(N).
Problem H: Horrbly Fast-Calc! • TestData & Solution: MahdiSafarNejad • Task: Find sum of all positive divisors of numbers in a range. • 99 out of 135 teams submitted. 61 teams got AC. • Good Idea: • Find each primes’s impact in final result one by one. • Slow codes could get AC as someone was generous!
Problem I: Intergalactic souvenirs! • Author: Aideen NasiriShargh • TestData & Solution: Aideen NasiriShargh • Task: Given some pre-comparisons of some objects; you are to find minimum and maximum of them (in weight) with the least number of balances. • 4 out of 135 teams submitted. 9 teams got AC.
Problem I: Intergalactic souvenirs! • First of all, is it inconsistent? • Have a directed graph, you want to find if it has a cycle or not in O(N+E). • You need to have 3 colors and find double-reached gray vertex. • Second, find minimum number of additional weightings. • For each object we have CanBeMin[x] and CanBeMax[x] which are all initially true.
Problem I: Intergalactic souvenirs! • After given comparisons, objects are in 4 type: • A: CanBeMin and CanBeMax • B: CanBeMin and !CanBeMax • C: !CanBeMin and CanBeMax • D: !CanBeMin and !CanBeMax • Drop D’s! • Each comparison between X and Y can make • !CanBeMin[X] and !CanBeMax[Y] (if X > Y) • !CanBeMax[X] and !CanBeMin[Y] (if Y > X)
Problem I: Intergalactic souvenirs! • Each object in B or C need at least one comparison. • Each object in group A needs one comparison and then one comes to B and one comes to C. • So the answer is • A + (B+A/2 -1) + (C+A/2 -1) • If B=C=0 then answer is ceil(3N/2)