题面:

C. Team Tic Tac Toe

Input file: standard input
Output file: standard output
Time limit: 1 second
Memory limit: 256 megabytes
 
Farmer John owns 26 cows, which by happenstance all have names starting with different letters of the alphabet, so Farmer John typically refers to each cow using her first initial – a character in the range A…ZA…Z.
The cows have recently become fascinated by the game of tic-tac-toe, but since they don’t like the fact that only two cows can play at a time, they have invented a variant where multiple cows can play at once! Just like with regular tic-tac-toe, the game is played on a 3×3 board, only instead of just Xs and Os, each square is marked with a single character in the range A...Z to indicate the initial of the cow who claims that square.
An example of a gameboard might be:

COW
XXO
ABC

The cows fill in each of the nine squares before they become confused about how to figure out who has won the game. Clearly, just like with regular tic-tac-toe, if any single cow has claimed an entire row, column, or diagonal, that cow could claim victory by herself. However, since the cows think this might not be likely given the larger number of players, they decide to allow cows to form teams of two, where a team of two cows can claim victory if any row, column, or diagonal consists only of characters belonging to the two cows on the team, and moreover if characters from both cows (not just one) are used in this row, column, or diagonal.
Please help the cows figure out how many individuals or two-cow teams can claim victory. Note that the same square on the game board might possibly be usable in several different claims to victory.
 
 
Input
The input consists of three lines, each of which is three characters in the range A...Z.
 
Output
Output should consist of two lines. On the first line, output the number of individual cows who can claim victory. On the second line, output the number of two-cow teams that could claim victory.
 
Example
Input
COW
XXO
ABC
Output
0
2
 
Note
In this example, no single cow can claim victory. However, if cows C and X team up, they can win via the C-X-C diagonal. Also, if cows X and O team up, they can win via the middle row.
 
 

题目描述:

有26头奶牛,它们的名字分别对应26个字母。最近,奶牛迷上了一款游戏,但是这款游戏只能两头牛同时玩,然后它们发明了一款可以同时多头牛玩的游戏,游戏规则大概是:每头牛都会在一个3 x 3的九宫格里面填上自己的名字,如果有一头牛能占据一整行,或一整列,或者是对角线,那么就说这头牛自称“赢”了。但是,奶牛们考虑到这样只有很少头牛能“赢”,所以,就允许两头奶牛直接组队。如果两头奶牛组队以后能“一起”(这里的“一起”指的是一定要包含两头牛)占据一整行,或一整列,或者对角线,那么,这两头牛组成的队伍“赢”了。现在要求:1.有多少头牛自称“赢”了;2.有多少支由两头牛组成的队伍“赢”了。
 

题目分析:

这道题刚开始题目没有仔细看题目,理解错了。再次看题目时发现有些情况重复计算,改了一下就AC了。
 
下面进入正题:
其实这道题一看这么小,直接暴力就能弄出来了。但是,我的想法也太暴力了,没经过任何思考,代码又长又丑。看了大神的代码才知道原来是这样写的(吐槽博主还没进入正题( ̄_ ̄|||) )。
我先讲讲我的思路(大佬略过,新人慎看,容易被误导):我写了一个检查函数,这个函数可以检测某一个字母是否包含一整行,一整列,还有对角线。然后我从字母A-Z遍历一遍就能求到问题1了,但是呢,问题2怎么求?其实只要从图中任意选两头牛出来就行了,也就是9*9=81的可能,之后用另一个临时二维数组存图,只需要把这两头牛变成同一头牛就可以用检查函数了,然后再把图还原回来,所以又写了一个还原函数。最后用vis数组标记算过的情况,然后就搞定了,AC(恶心)代码如下:
  1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <cmath>
5 #include <set>
6 #include <algorithm>
7 using namespace std;
8 char mymap[5][5];
9 char temp[5][5];
10 int vis[128][128];
11
12 bool check(char ch){
13 int flag;
14 for(int i = 0; i < 3; i++){
15 flag = 1;
16 for(int j = 0; j < 3; j++){
17 if(ch != temp[i][j]) flag = 0;
18 }
19 if(flag) return true;
20 }
21
22 for(int j = 0; j < 3; j++){
23 flag = 1;
24 for(int i = 0; i < 3; i++){
25 if(ch != temp[i][j]) flag = 0;
26 }
27 if(flag) return true;
28 }
29
30 flag = 1;
31 for(int i = 0; i < 3; i++){
32 if(temp[i][i] != ch) flag = 0;
33 }
34 if(flag) return true;
35
36 flag = 1;
37 for(int i = 0; i < 3; i++){
38 if(temp[i][2-i] != ch) flag = 0;
39 }
40 if(flag) return true;
41
42 return false;
43 }
44
45 void reback(){
46 for(int i = 0; i < 3; i++){
47 for(int j = 0; j < 3; j++){
48 temp[i][j] = mymap[i][j];
49 }
50 }
51 }
52
53 void cover(char a, char b){
54 for(int i = 0; i < 3; i++){
55 for(int j = 0; j < 3; j++){
56 if(temp[i][j] == a) temp[i][j] = b;
57 }
58 }
59 }
60
61 void test(){
62 cout <<endl;
63 for(int i = 0; i < 3; i++){
64 for(int j = 0; j < 3; j++){
65 cout << temp[i][j];
66 }
67 cout << endl;
68 }
69
70 }
71
72 int main(){
73 for(int i = 0; i < 3; i++){
74 cin >> mymap[i];
75 }
76
77 reback();
78 //test();
79
80
81 char st[15];
82 int top = 0;
83
84 int cnt1 = 0;
85 for(char i = 'A'; i <= 'Z'; i++){
86 if(check(i)) { cnt1++; st[top++] = i;}
87 }
88 cout << cnt1 << endl;
89
90 for(int i = 0; i < top; i++){
91 int u1 = st[i];
92 for(int j = 0; j < top; j++){
93 int u2 = st[j];
94 vis[u1][u2] = vis[u2][u1] = 1;
95 }
96 }
97
98 int cnt = 0;
99
100
101 for(int ai = 0; ai < 3; ai++){
102 for(int aj = 0; aj < 3; aj++){
103 char ch1 = mymap[ai][aj];
104
105 for(int bi = 0; bi < 3; bi++){
106 for(int bj = 0; bj < 3; bj++){
107 char ch2 = mymap[bi][bj];
108 reback();
109 cover(ch1, ch2);
110
111 //test();
112 if(check(ch2) && !vis[ch1][ch2]) {
113 cnt++;
114 vis[ch1][ch2] = vis[ch2][ch1] = 1;
115 }
116 }
117 }
118 }
119 }
120
121 cout << cnt << endl;
122 return 0;
123 }
但是这个代码巨长(太暴力了),而且很容易出bug(足足花费1小时才写好这个水题),接下来我们讲讲大佬的优秀代码:
首先,我们可以分析一下这道题:要判断一整行,列,对角线是否被同样的牛占据,是不是只要判断一整行,列,对角线的三个元素(字母)是否相等?由此,我们就可以遍历一遍所有行,列,对角线是否被同样的牛占据,这样就可以解决问题1了。问题2呢?其实也是同样的道理:如果只有两头牛占据同一行,列,对角线,那么它们组队后就肯定是“赢”了。只要我们用数组标记这些牛(一维数组),这些  “牛”对(二维数组)被访问过,就可以通过遍历一遍数组来计算出“赢”的个数,不过这里要注意重复的问题。根据上面的想法,我们可以编写一个check函数,检查三个字母是否相等(一头牛“赢”的情况),或者是只有两个字母相等,也就是只有两种字母(对应两头牛组队“赢”的情况),然后在遍历每条边,列,对角线时都执行这个函数就可以完成这道题了。
 
补充:关于重复问题,我们可以这样想:对于一些牛,我怎样才能计算选出两头牛而且这些 "牛"对 不重复的个数,就像这样:
显然答案是C(5, 2),但是没学组合数之前,我们是不是这样算:
这样就得到了(A,B), (A,C), (A,D), (A,E)
接下来怎样算才不会重复呢?其实也就是这样:
这样我们是不是得到了(B,C), (B,D), (B, E)。之后反复执行这个操作就行了
也就是说,当我们遍历 “牛”对 (二维数组)时,通过这种方式就可以检查不同的 “牛”对 之间是否“赢”了,是不是有点神奇(ง •_•)ง,既不会漏也不会重复。怎样写见下面代码:
 
 
AC代码:
 1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <cmath>
5 #include <set>
6 #include <map>
7 #include <algorithm>
8 using namespace std;
9 char g[5][5]; //图
10 int G[5][5]; //转化为整数
11 int win[30], win2[30][30]; //标记数组
12
13 void check(int a, int b, int c){
14 if(a == b && b == c) win[a] = 1; //对应一头牛“赢”的情况
15 else if(a == b && b != c) //下面两个个else if都是其中两头牛组队赢的情况
16 win2[a][c] = win2[c][a] = 1; //双向都要标记一下,去重的关键
17 else if(a == c && b != c)
18 win2[a][b] = win2[b][a] = 1;
19 else if(b == c && a != c)
20 win2[b][a] = win2[a][b] = 1;
21 }
22
23 int main(){
24 for(int i = 0; i < 3; i++) cin >> g[i];
25
26 for(int i = 0; i < 3; i++){
27 for(int j = 0; j < 3; j++){
28 G[i][j] = g[i][j]-'A'; //把字母转化为对应的数字,方便开数组
29 }
30 }
31
32 for(int i = 0; i < 3; i++){
33 check(G[i][0], G[i][1], G[i][2]); //每行
34 check(G[0][i], G[1][i], G[2][i]); //每列
35 }
36
37 check(G[0][0], G[1][1], G[2][2]); //正对角线
38 check(G[0][2], G[1][1], G[2][0]); //负对角线
39
40 int ans = 0;
41 for(int i = 0; i < 26; i++) ans += win[i]; //统计一头牛“赢”的情况
42
43 int ans2 = 0;
44 for(int i = 0; i < 26; i++){ //统计两头牛组队后“赢”的情况
45 for(int j = i+1; j < 26; j++){ //去重关键,只要遍历比i大的牛就行了
46 ans2 += win2[i][j];
47 }
48 }
49
50 cout << ans << endl << ans2 << endl;
51 return 0;
52 }
 
 
 

2019 GDUT Rating Contest III : Problem C. Team Tic Tac Toe的更多相关文章

  1. 2019 GDUT Rating Contest III : Problem D. Lemonade Line

    题面: D. Lemonade Line Input file: standard input Output file: standard output Time limit: 1 second Memo ...

  2. 2019 GDUT Rating Contest III : Problem E. Family Tree

    题面: E. Family Tree Input file: standard input Output file: standard output Time limit: 1 second Memory ...

  3. 2019 GDUT Rating Contest III : Problem A. Out of Sorts

    题面: 传送门 A. Out of Sorts Input file: standard input Output file: standard output Time limit: 1 second M ...

  4. 2019 GDUT Rating Contest II : Problem F. Teleportation

    题面: Problem F. Teleportation Input file: standard input Output file: standard output Time limit: 15 se ...

  5. 2019 GDUT Rating Contest I : Problem B. Teamwork

    题面: 传送门 B. Teamwork Input file: standard input Output file: standard output Time limit: 1 second Memor ...

  6. 2019 GDUT Rating Contest I : Problem H. Mixing Milk

    题面: H. Mixing Milk Input file: standard input Output file: standard output Time limit: 1 second Memory ...

  7. 2019 GDUT Rating Contest I : Problem A. The Bucket List

    题面: A. The Bucket List Input file: standard input Output file: standard output Time limit: 1 second Me ...

  8. 2019 GDUT Rating Contest I : Problem G. Back and Forth

    题面: G. Back and Forth Input file: standard input Output file: standard output Time limit: 1 second Mem ...

  9. 2019 GDUT Rating Contest II : Problem G. Snow Boots

    题面: G. Snow Boots Input file: standard input Output file: standard output Time limit: 1 second Memory ...

随机推荐

  1. spring再学习之注解

    1.使用注解配置spring <?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi= ...

  2. 【非原创】codeforces 1025D - Recovering BST【区间dp+二叉搜索树】

    题目:戳这里 题意:给一个不下降序列,有n个数.问能否构造一个二叉搜索树,满足父亲和儿子之间的gcd>1. 解题思路:其实这题就是构造个二叉搜索树,只不过多了个条件.主要得了解二叉搜索树的性质, ...

  3. IFIX 5.9 历史数据 曲线 (非SQL模式)

    装完 ifix 5.9 默认是没有Hist 开头的 历史数据源的,没存,至少我装的版本是这样. 那个Historian 也没有安装包,好像还要授权,自己研究不了. 1 先把数据存本地 在你的安装包里 ...

  4. Windows font-size: 10px; bug

    Windows font-size: 10px; bug Windows 最小只能渲染 font-size: 12px; ???屏幕分辨率 macOS 正常渲染 10px PC 最小只能渲染 font ...

  5. Linux cp command All In One

    Linux cp command All In One $ man cp $ cp -h # 强制 $ cp -f # 递归,复制文件夹 $ cp -r demos cp -fr # ./folder ...

  6. Google Tag Manager

    Google Tag Manager SEO https://www.wappalyzer.com/technologies/tag-managers/google-tag-manager/ UTM ...

  7. webpack 5

    webpack 5 webpack 5 requires at least Node.js 10.13.0 (LTS). https://webpack.js.org/migrate/5/ https ...

  8. auto scroll bottom in js

    auto scroll bottom in js autoScrollToBottom() { let box = document.querySelector(`[data-dom="ch ...

  9. css social media

    css social media https://realfavicongenerator.net/ https://css-tricks.com/favicon-quiz/ <!DOCTYPE ...

  10. Java NIO wakeup实现原理

    本文转载自Java NIO wakeup实现原理 导语 最近在阅读netty源码时,很好奇Java NIO中Selector的wakeup()方法是如何唤醒selector的,于是决定深扒一下wake ...