Now you have first-hand experience about what happens when you don't normalize your database. 🙂
Since nothing is unique it becomes a little bit harder. I don't know if the following will be better or worse, try it to find out. Note that it is untested.
select name from (
select * from table where type = 1 and (cat = 3 or cat = 4) group by name, cat
) group by name having count(*) = 2
Basically the subquery is to retreive the rows that could be used and the main query is to see if there are two rows, one with cat = 3 and one with cat = 4. In the subquery it may possibly be quicker to use "and cat in (3, 4)".
By the way, correct indexing would really speed the queries up. In fact, indexing is often forgotten when it is the solution.
There have to be other ways to do the query, but this is the most obvious way that I can think of. And normalize in the future to make it easier 😉