Skip to content

Commit a953886

Browse files
Merge pull request #4078 from NimeeshS/master
create internal solution for usaco-1180 (non-transitive dice)
2 parents 8dc5cbf + a157044 commit a953886

File tree

2 files changed

+170
-2
lines changed

2 files changed

+170
-2
lines changed

content/extraProblems.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,7 @@
611611
"isStarred": false,
612612
"tags": ["Complete Search"],
613613
"solutionMetadata": {
614-
"kind": "USACO",
615-
"usacoId": "1180"
614+
"kind": "internal"
616615
}
617616
},
618617
{

solutions/bronze/usaco-1180.mdx

+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
id: usaco-1180
3+
source: USACO Bronze 2022 January
4+
title: Non-Transitive Dice
5+
author: Nimeesh Sharma
6+
---
7+
8+
[Official Analysis (C++, Java, Python)](http://www.usaco.org/current/data/sol_prob2_bronze_jan22.html)
9+
10+
## Explanation
11+
12+
To begin with this problem, we must first understand what it means for three dice to be transitive.
13+
Dice are transitive when dice $A$ beats dice $B$, dice $B$ beats dice $C$, and dice $C$ beats dice $A$.
14+
Dice $A$ beats dice $B$ when there are more pairs $(x, y)$ where $x$ is a side of dice $A$ and $y$ is a side on dice $B$ where $x > y$ compared to when $y < x$.
15+
16+
Since each dice has four sides and there are ten possible values for each side, there are $10^4 = 10,000$ possible dice to test.
17+
This number is small enough that we can test every possible dice for non-transitivity via brute force.
18+
19+
## Implementation
20+
21+
**Time Complexity**: $\mathcal{O}(1)$ for each test case
22+
23+
<LanguageSection>
24+
<CPPSection>
25+
26+
```cpp
27+
#include <bits/stdc++.h>
28+
using namespace std;
29+
30+
using Die = array<int, 4>;
31+
32+
/** @return whether dice A beats dice B */
33+
bool beats(const Die &a, const Die &b) {
34+
int wins = 0, losses = 0;
35+
for (int i = 0; i < 4; i++) {
36+
for (int j = 0; j < 4; j++) {
37+
if (a[i] > b[j]) { wins++; }
38+
if (a[i] < b[j]) { losses; }
39+
}
40+
}
41+
return wins > losses;
42+
}
43+
44+
int main() {
45+
int test_num;
46+
cin >> test_num;
47+
for (int i = 0; i < test_num; i++) {
48+
Die A, B;
49+
string ans = "no";
50+
for (int j = 0; j < 4; j++) { cin >> A[j]; }
51+
for (int j = 0; j < 4; j++) { cin >> B[j]; }
52+
53+
// Iterate through all 10,000 possibilities
54+
// and check if there is a possible transitive dice
55+
for (int a = 1; a <= 10; a++) {
56+
for (int b = 1; b <= 10; b++) {
57+
for (int c = 1; c <= 10; c++) {
58+
for (int d = 1; d <= 10; d++) {
59+
Die C{a, b, c, d};
60+
if (beats(A, B) && beats(B, C) && beats(C, A)) {
61+
ans = "yes";
62+
}
63+
if (beats(B, A) && beats(C, B) && beats(A, C)) {
64+
ans = "yes";
65+
}
66+
}
67+
}
68+
}
69+
}
70+
71+
cout << ans << "\n";
72+
}
73+
}
74+
```
75+
76+
</CPPSection>
77+
<JavaSection>
78+
79+
```java
80+
import java.io.BufferedReader;
81+
import java.io.IOException;
82+
import java.io.InputStreamReader;
83+
import java.util.StringTokenizer;
84+
85+
public class NonTransitiveDice {
86+
/** @return whether dice A beats dice B */
87+
static boolean beats(int[] dice1, int[] dice2) {
88+
int diff = 0;
89+
for (int x : dice1) {
90+
for (int y : dice2) { diff += Integer.signum(x - y); }
91+
}
92+
return diff > 0;
93+
}
94+
95+
public static void main(String[] args) throws IOException {
96+
BufferedReader in =
97+
new BufferedReader(new InputStreamReader(System.in));
98+
StringBuilder out = new StringBuilder();
99+
for (int n = Integer.parseInt(in.readLine()); n > 0; n--) {
100+
StringTokenizer tokenizer = new StringTokenizer(in.readLine());
101+
int[] diceA = new int[4];
102+
for (int j = 0; j < 4; j++) {
103+
diceA[j] = Integer.parseInt(tokenizer.nextToken());
104+
}
105+
int[] diceB = new int[4];
106+
for (int j = 0; j < 4; j++) {
107+
diceB[j] = Integer.parseInt(tokenizer.nextToken());
108+
}
109+
110+
String ans = "no";
111+
// Iterate through all 10,000 possibilities
112+
// and check if there is a possible transitive dice
113+
for (int a = 1; a <= 10; a++) {
114+
for (int b = 1; b <= 10; b++) {
115+
for (int c = 1; c <= 10; c++) {
116+
for (int d = 1; d <= 10; d++) {
117+
int[] diceC = {a, b, c, d};
118+
if (beats(diceA, diceB) && beats(diceB, diceC) &&
119+
beats(diceC, diceA)) {
120+
ans = "yes";
121+
}
122+
if (beats(diceB, diceA) && beats(diceA, diceC) &&
123+
beats(diceC, diceB)) {
124+
ans = "yes";
125+
}
126+
}
127+
}
128+
}
129+
}
130+
131+
out.append(ans).append('\n');
132+
}
133+
134+
System.out.print(out);
135+
}
136+
}
137+
```
138+
139+
</JavaSection>
140+
<PySection>
141+
142+
```py
143+
def win(a: list[int], b: list[int]) -> bool:
144+
""":return: whether dice A beats dice B."""
145+
return sum([x > y for x in a for y in b]) > sum([y > x for x in a for y in b])
146+
147+
148+
for _ in range(int(input)):
149+
l = [int(x) for x in input().split()]
150+
a_die = l[0:4]
151+
b_die = l[4:8]
152+
153+
ans = "no"
154+
# Iterate through all 10,000 possibilities and check if there is a possible transitive dice
155+
for a in range(1, 11):
156+
for b in range(1, 11):
157+
for c in range(1, 11):
158+
for d in range(1, 11):
159+
c_die = [a, b, c, d]
160+
if win(a_die, b_die) and win(b_die, c_die) and win(c_die, a_die):
161+
ans = "yes"
162+
if win(b_die, a_die) and win(c_die, b_die) and win(a_die, c_die):
163+
ans = "yes"
164+
165+
print(ans)
166+
```
167+
168+
</PySection>
169+
</LanguageSection>

0 commit comments

Comments
 (0)