[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
原题:問題「荒れ果てたショップ」 | エンジニアが死滅シタ世界 〜アンドロイドとふたりぼっちで生きろ〜
你正在整理商店管理系统的文件。
每个文件有编号与之对应,为了让文件的编号看起来比较一致,比较短的数字需要在左边补0至长度相同。
例如,编号的长度为3时,0应该补成000,而4应该补成004,13补成013,144不需要补0因此就是144,诸如此类。
给你三个整数N、A和B。
你需要将区间[A, B]中的整数补0至长度都为N,然后输出他们。
例如,样例1可以表示为下图。
在这个样例中,你需要将9、10和11三个数字补成长度为3的统一形式。
N A B
将区间[A, B]中的每一个整数i补成长度为N的形式并分别输出他们。
输出的最后应该包含一个换行符。
输入:
3 9 11
输出:
009
010
011
输入:
2 0 3
输出:
00
01
02
03
// 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;
}
int n, a, b;
char fmt[10];
int main() {
n = readint(); a = readint(); b = readint();
sprintf(fmt, "%%0%dd\n", n);
for(int i = a; i <= b; i++) {
printf(fmt, i);
}
return 0;
}
Translation by KSkun
原题:問題「高層タワー」 | エンジニアが死滅シタ世界 〜アンドロイドとふたりぼっちで生きろ〜
你在把一些单词组合成新的单词。
新单词由N个字符串按先后顺序结合而成。
为了避免新单词过于冗长,需要将前一个单词的末端与后一个单词的前端最长的相同子串合并起来。
例如,样例1中需要合并paiza
、apple
和letter
三个单词,
前两个单词paiza
和apple
按要求合并后得到了paizapple
这个单词。
再合并上后一个单词就得到了paizappletter
。
注意,必须按从前到后的顺序合并,样例2中合并poh
、p
、oh
时,
poh
和p
合并得到了pohp
,此时再合并oh
得到的是pohpoh
。
请按照输入的先后顺序合并给出的N个字符串得到新单词。
N
w_1
w_2
...
w_N
输出N个单词按输入先后顺序结合成的新单词。
输入:
3
paiza
apple
letter
输出:
paizappletter
输入:
3
poh
p
oh
输出:
pohpoh
// Code by KSkun, 2019/1
#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;
}
const int MAXN = 10005;
int n, rlen = 0, len;
char res[MAXN], w[MAXN];
inline bool issame(int len) {
for(int i = 1; i <= len; i++) {
if(res[rlen - (len - i)] != w[i]) return false;
}
return true;
}
inline int solve(int len) {
for(int i = std::min(rlen, len); i >= 1; i--) {
if(issame(i)) return i;
}
return 0;
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%s", w + 1);
len = strlen(w + 1);
int r = solve(len);
for(int i = 1; i <= len - r; i++) {
res[rlen + i] = w[r + i];
}
rlen += len - r;
}
printf("%s", res + 1);
return 0;
}