2

I have found a solution to this Kattis Problem:

https://open.kattis.com/problems/funnygames

but it uses >?= unix syntax which I need to change to compile in Kattis. I changed them to std::min and std::max respectively, but I'm not getting the right answer (I get Michael everytime).

Original Code:

/* Sample solution to "Funny Games" from NCPC 2005
 * Algorithm: essentially continuous DP, keep track of winning intervals
 * Author: Per Austrin
 */ 
#include <cmath>
#include <cassert>
#include <algorithm>
#include <cstdio>

using namespace std;

typedef pair<double, double> pdd;

template <class It, class OIt>
OIt ival_union(It begin, It end, OIt dest) {
  sort(begin, end);
  while(begin != end) {
    *dest = *begin++;
    while(begin != end && begin->first < dest->second + 1e-8)
      dest->second >?= begin++->second; //Change 1
    ++dest;
  }
  return dest;
}   

int main(void) {
  int n, k;
  double x, f[10], maxf;
  pdd win[10000], lose;
  for (scanf("%d", &n); n--; ) {
    scanf("%lf%d", &x, &k);
    maxf = lose.second = 0;
    for (int i = 0; i < k; ++i)
      scanf("%lf", f+i), win[i] = make_pair(1, 1 / f[i]), maxf >?= f[i];  //Change 2
    for (int nwin = k, l = 0; x > lose.second; ++l) {
      nwin = ival_union(win + l , win + nwin, win + l) - win;
      lose.second = (lose.first = win[l].second) / maxf;
      if (l < nwin-1) lose.second <?= win[l+1].first; //Change 3
      for (int i = 0; i < k; ++i)
    win[nwin++] = make_pair(lose.first/f[i], lose.second/f[i]);
    }
    assert(fabs(x-lose.first) > 1e-6 && fabs(x-lose.second) > 1e-6);
    printf("%s\n", x < lose.first ? "Nils" : "Mikael");
  }
}

And my 3 changes:

std::max(dest->second, begin++->second); //Change 1

scanf("%lf", f + i), win[i] = make_pair(1, 1 / f[i]), std::max(maxf, f[i]); //Change 2

if (l < nwin - 1) std::min(lose.second, win[l + 1].first); //Change 3

The input is

4
6 2 0.25 0.5
10 2 0.25 0.5
29.29 4 0.3 0.7 0.43 0.54
29.30 4 0.3 0.7 0.43 0.54

The output should be

Mikael
Nils
Nils
Mikael

But after the changes I get

Mikael
Mikael
Mikael
Mikael
Seth Kitchen
  • 1,526
  • 19
  • 53
  • 1
    When you used the debugger, where does the program deviate from the logic that you've written? And what's the reason for the unorthodox usage of `scanf`? Why not simply `cin`, `getline`, or some other saner C++ idiom? – PaulMcKenzie Dec 23 '16 at 03:08
  • @PaulMcKenzie I stole this code from the solution manual https://ncpc.idi.ntnu.no/ncpc2005/ I will run through with a debugger now – Seth Kitchen Dec 23 '16 at 03:13
  • The ideal way to debug this is to have two programs where one program has the original implementation and the other has your changes. You can then debug both "simultaneously" and see where your program goes in a different direction than the original program. – PaulMcKenzie Dec 23 '16 at 03:17
  • [Why is “using namespace std” considered bad practice?](http://stackoverflow.com/q/1452721/995714) – phuclv Dec 23 '16 at 03:20
  • 3
    `>?=` ? Since no one else has questioned it I'm assuming it is a real thing but one that I don't know (and it seems neither does google) - anyone care to explain? – John3136 Dec 23 '16 at 03:20
  • 3
    @John3136 I think that's why I'm having so much trouble. Only documentation I can find says its min and max http://stackoverflow.com/questions/16126507/operator-c-greater-less-question-mark-equals-sign . I can't find a unix compiler that accepts it so I'm having trouble debugging – Seth Kitchen Dec 23 '16 at 03:24
  • @SethKitchen Ah-ha. Good find. They are gcc extensions. Now the question makes sense ;-) – John3136 Dec 23 '16 at 03:27
  • 1
    Apparently `a>?=b` is `a=max(a,b)`, and it has been deprecated. – DYZ Dec 23 '16 at 03:27
  • @DYZ your comment made a lightbulb go off, thanks – Seth Kitchen Dec 23 '16 at 03:33

1 Answers1

0

After reading over the comments I realized I did max(a,b), but didn't do a=max(a,b) so after I made that change it works as expected. The changes are:

dest->second=std::max(dest->second, begin++->second);

scanf("%lf", f + i), win[i] = make_pair(1, 1 / f[i]), maxf=std::max(maxf, f[i]);

if (l < nwin - 1) lose.second=std::min(lose.second, win[l + 1].first);

Thanks for the help!

Seth Kitchen
  • 1,526
  • 19
  • 53