[CSP-S2 2019]格雷码 题解
题目地址:ė …
May all the beauty be blessed.
题目地址:Codeforces:Problem – 3C – Codeforces、洛谷:CF3C Tic-tac-toe – 洛谷 | 计算机科学教育新生态
Certainly, everyone is familiar with tic-tac-toe game. The rules are very simple indeed. Two players take turns marking the cells in a 3 × 3 grid (one player always draws crosses, the other — noughts). The player who succeeds first in placing three of his marks in a horizontal, vertical or diagonal line wins, and the game is finished. The player who draws crosses goes first. If the grid is filled, but neither Xs, nor 0s form the required line, a draw is announced.
You are given a 3 × 3 grid, each grid cell is empty, or occupied by a cross or a nought. You have to find the player (first or second), whose turn is next, or print one of the verdicts below:
illegal
— if the given board layout can’t appear during a valid game;the first player won
— if in the given board layout the first player has just won;the second player won
— if in the given board layout the second player has just won;draw
— if the given board layout has just let to a draw.给一个井字棋(三子棋)的局面,请判断该局面的状态,状态有以下几种:
井字棋玩法请百度。
输入格式:
The input consists of three lines, each of the lines contains characters “.”, “X” or “0” (a period, a capital letter X, or a digit zero).
输出格式:
Print one of the six verdicts: first
, second
, illegal
, the first player won
, the second player won
or draw
.
输入样例#1:
X0X .0. .X.
输出样例#1:
second
大模拟题,细节和分类特别多。分状态讨论符合的情况。
下一步X下棋,仅出现于合法且无人获胜的局面中,特征是局面中X和O的数量相同。
下一步O下棋,仅出现于合法且无人获胜的局面中,特征是局面中X比O的数量多1。
非法状态,有以下几类:X与O的数量的关系既不是相同也不是X比O多1;X获胜之后O仍然下了一步棋(X获胜之后X与O数量相同);O获胜之后X仍然下了一步棋(O获胜之后X比O数量多1)。
X获胜,合法局面中X棋子占据了某一行、列或正副对角线。
O获胜,合法局面中O棋子占据了某一行、列或正副对角线。
平局,合法局面,无人获胜,且棋盘中没有空位。
调试的时候平均一个submission过一个测试点,果然还是我太菜了。
// Code by KSkun, 2019/6
#include <cstdio>
char a[5][5];
int main() {
scanf("%s%s%s", a[1] + 1, a[2] + 1, a[3] + 1);
int cntx = 0, cnto = 0;
bool hasdot = false;
for(int i = 1; i <= 3; i++) {
for(int j = 1; j <= 3; j++) {
if(a[i][j] == 'X') cntx++;
if(a[i][j] == '0') cnto++;
if(a[i][j] == '.') hasdot = true;
}
}
if(cntx != cnto && cntx != cnto + 1) {
puts("illegal"); return 0;
}
bool fw = false, sw = false;
for(int i = 1; i <= 3; i++) {
if(a[i][1] == a[i][2] && a[i][2] == a[i][3]) {
if(a[i][1] == 'X') fw = true;
else if(a[i][1] == '0') sw = true;
}
}
for(int i = 1; i <= 3; i++) {
if(a[1][i] == a[2][i] && a[2][i] == a[3][i]) {
if(a[1][i] == 'X') fw = true;
else if(a[1][i] == '0') sw = true;
}
}
if(a[1][1] == a[2][2] && a[2][2] == a[3][3]) {
if(a[1][1] == 'X') fw = true;
else if(a[1][1] == '0') sw = true;
}
if(a[1][3] == a[2][2] && a[2][2] == a[3][1]) {
if(a[1][3] == 'X') fw = true;
else if(a[1][3] == '0') sw = true;
}
if(fw && sw) puts("illegal");
else if(fw && cntx != cnto + 1) puts("illegal");
else if(sw && cntx != cnto) puts("illegal");
else if(fw) puts("the first player won");
else if(sw) puts("the second player won");
else if(!hasdot) puts("draw");
else if(cntx == cnto) puts("first");
else if(cntx == cnto + 1) puts("second");
return 0;
}
Translation by KSkun
原题:問題「隔離された街のゲート」 | エンジニアが死滅シタ世界 〜アンドロイドとふたりぼっちで生きろ〜
你找到了一个未完成的游戏程序,这个游戏没有实现控制角色移动的方法。
这个未完成的游戏使用宽为 W 高为 H 的网格图作为地图。
左下角的点是原点,坐标是 (0, 0) 。
从原点横向前进 x 单位,纵向前进 y 单位到达的点坐标表示为 (x, y) 。
现在由于处于开发阶段,地图上没有障碍物,角色的初始坐标为 (0, 0) 。
从该状态开始,执行总共 N 个的向上、下、左或右的移动操作。
各个移动操作对角色坐标 (x, y) 的更改情况如下所示:
在开发需求文档中,需要编写一个能够判断角色在 N 次移动操作的过程中是否处于不合法的坐标上。
这里的不合法的坐标指的是在地图之外的坐标,也就是地图上不存在的坐标。
例如,输入输出样例1和2可以表示如下。
H W N
d_1
...
d_N
在 N 次移动操作中,如果角色到达了不合法的坐标,则输出一行“invalid”,否则输出一行“valid”。
输入:
3 3 5
U
R
D
R
L
输出:
valid
输入:
4 4 7
U
U
R
R
R
R
D
输出:
invalid
// Code by KSkun, 2019/5
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
typedef long long LL;
inline char fgc() {
static char buf[100000], *p1 = buf, *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
? EOF : *p1++;
}
inline LL readint() {
LL res = 0, neg = 1; char c = fgc();
for(; !isdigit(c); c = fgc()) if(c == '-') neg = -1;
for(; isdigit(c); c = fgc()) res = res * 10 + c - '0';
return res * neg;
}
inline char readsingle() {
char c;
while(!isgraph(c = fgc())) {}
return c;
}
inline bool isop(char c) {
return c == 'U' || c == 'D' || c == 'R' || c == 'L';
}
inline char readop() {
char c;
while(!isop(c = fgc())) {}
return c;
}
int n, m, N;
int main() {
n = readint(); m = readint(); N = readint();
int nx = 0, ny = 0;
while(N--) {
char op = readop();
if(op == 'U') ny++;
else if(op == 'D') ny--;
else if(op == 'L') nx--;
else if(op == 'R') nx++;
if(nx < 0 || nx >= n || ny < 0 || ny >= m) {
puts("invalid");
return 0;
}
}
puts("valid");
return 0;
}
Translation by KSkun
原题:問題「学べない学校」 | エンジニアが死滅シタ世界 〜アンドロイドとふたりぼっちで生きろ〜
学校里的孩子们在玩剪刀石头布。特别是A君和B君,每天都要来上几盘,两人争来争去非要比个高下。
你知道了两个人的游戏记录,他们想让你写一个程序来判定他们谁最强。
A君和B君一共进行了N次游戏。
你知道了他们进行的游戏次数N以及每一次的状况,你需要写一个统计A君和B君获胜次数的程序。
剪刀石头布有三种手势:剪刀、石头、步。
石头可以赢剪刀,剪刀赢布,布赢石头。
输入中:
g
表示c
表示p
表示样例1的说明如下图所示。
N
a_1 b_1
a_2 b_2
...
a_N b_N
以以下的格式分别输出A君和B君获胜的次数。
w_a
w_b
g
、c
和p
中的一种。输入:
3
g g
c p
p g
输出:
2
0
输入:
10
p g
c c
p p
g g
c p
c p
g g
p p
g p
p g
输出:
4
1
// Code by KSkun, 2019/1
#include <cstdio>
#include <cctype>
#include <algorithm>
typedef long long LL;
inline char fgc() {
static char buf[100000], *p1 = buf, *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
? EOF : *p1++;
}
inline LL readint() {
LL res = 0, neg = 1; char c = fgc();
for(; !isdigit(c); c = fgc()) if(c == '-') neg = -1;
for(; isdigit(c); c = fgc()) res = res * 10 + c - '0';
return res * neg;
}
inline char readsingle() {
char c;
while(!isgraph(c = fgc())) {}
return c;
}
inline int win(char a, char b) {
if(a == b) return 0;
if(a == 'g' && b == 'c') return 1;
if(a == 'c' && b == 'p') return 1;
if(a == 'p' && b == 'g') return 1;
return -1;
}
int n, cnta = 0, cntb = 0;
char wa[5], wb[5];
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%s%s", wa, wb);
int res = win(wa[0], wb[0]);
if(res > 0) cnta++;
else if(res < 0) cntb++;
}
printf("%d\n%d\n", cnta, cntb);
return 0;
}