I think that you cannot solve this problem easily working incrementally as you do. Moreover, your specs are a bit unclean, because you're asking for animal names, but you want to print out more info. What if HIPPO appears also in Indiana, but only one time? Would Indiana be printed (because it contains an animal that matches the specs) or wouldn't it (because the animal appears only one time)?

I usually find it cleaner to transform the data in something that is straightforward to analyse later, possibly using more logic passes. In this case, I see two distinct problems:

detection: you have to tell which animals match your rules

presentation: you have to print the way you like.

For the detection part, I'd use a hash of hashes in which the first index is the animal name, and the second is the name of the state. The elements would be the names of the zoos:

The '$cur eq $nxt' test will always compare an entry with itself at some time during each execution of the loop, thus finding a false duplicate. However, the print is driven by $count, which scopes within a state, which has the effect also of hiding the duplicate test. In a correct solution, duplicates need to be detected across states and the print needs to address a uniquified list of everything that was found in a successful duplicate test.

Update: As the other replies suggest - this uniquify idea is best implemented in a summary hash that matches your output.

Your solution does not take into account that the animal must "1.Occur more than once within the states, AND 2.Occur in more than one states.", it only checks that an animal occurs at least two times in the whole bighash.