原题:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=6&page=show_problem&problem=342
题目大意:
文中规定描述了如下三个概念:
1) “regular palindrome(常规回文)”: 从前往后读与从后往前读是一样的。
2) “mirrored string(镜式串)”: 对于字符串的中轴呈轴对称。
3) “mirrored palindrome(镜式回文)”: 同时满足1) 、2)条件的串。
对于镜式串的定义,还给出了有效的原字符及其对应的翻转字符表。
Character | Reverse | Character | Reverse | Character | Reverse |
A | A | M | M | Y | Y |
B | N | Z | 5 | ||
C | O | O | 1 | 1 | |
D | P | 2 | S | ||
E | 3 | Q | 3 | E | |
F | R | 4 | |||
G | S | 2 | 5 | Z | |
H | H | T | T | 6 | |
I | I | U | U | 7 | |
J | L | V | V | 8 | 8 |
K | W | W | 9 | ||
L | J | X | X |
注意,原题中说字母“o”和数字“0”可以看作相等的字符,因此只有字母“o”是合法字符。题意没错,只是把“o”和“0”打错了。
要求我们根据给出的长度1~20的字符串,判断其相应的类型,并输出规定的结果。
解题分析:
一道普通的字符串处理类的题目。判断类型的题目,我倾向于设置类型标识。根据处理得到的标识得到其类型。
伪代码:
1 保存原字符与翻转字符的对应关系。
2 判断是否为回文串。
2.1 是 -> 添加回文串标志。
2.2 不是 -> 空操作。
3 判断是否为镜式串。
3.1 是 ->添加镜式串标志。
3.2 不是 -> 空操作。
4 根据类型标志判断给定串的类型,输出相应结果。
源码:
/* * File: main.cpp * Author: lostaway * * Created on April 5, 2010, 11:29 PM */ #include <stdio.h> #include <stdlib.h> #include <string.h> /* * */ //characters and their reverses table. char CTable[30] = {'A', 'E', 'H', 'I', 'J', 'L', 'M', 'O', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '5', '8'}, RTable[30] = {'A', '3', 'H', 'I', 'L', 'J', 'M', 'O', '2', 'T', 'U', 'V', 'W', 'X', 'Y', '5', '1', 'S', 'E', 'Z', '8'}, input[30]; const int CRTableLen = 21; //功能:判断str串是否为回文串 int isPalindrome(char str[], int leftStart, int rightStart) { int i = leftStart, j = rightStart; while(1) { if(str[i] != str[j]) { return 0; } i--; j++; if(i < 0) { return 1; } } } //功能: 判断字符a的翻转字符是否为字符b int isReverse(char a, char b) { int i; for(i = 0; i < CRTableLen; i++) { if(a == CTable[i] || a == RTable[i]) { break; } } if(i >= CRTableLen) //this letter didn't has a reverse letter. { return 0; } if(a == CTable[i]) { if(b == RTable[i]) { return 1; } else { return 0; } } else if(a == RTable[i]) { if(b == CTable[i]) { return 1; } else { return 0; } } else { return 0; //只是为了让所有分支都有返回值,去除警告。 } } //功能: 判断串str是否为镜式串 int isMirrored(char str[], int leftStart, int rightStart) { int i = leftStart, j = rightStart; while(1) { if(isReverse(str[i], str[j]) == 0) { return 0; } i--; j++; if(i < 0) { return 1; } } } //功能: 根据tag标志输出相应的结果 void print(int tag) { switch(tag) { case 0: { printf("%s -- is not a palindrome./n", input); break; } case 1: { printf("%s -- is a regular palindrome./n", input); break; } case 10: { printf("%s -- is a mirrored string./n", input); break; } case 11: { printf("%s -- is a mirrored palindrome./n", input); break; } } printf("/n"); } int main(int argc, char** argv) { freopen("input.txt", "r", stdin); int middle, tag, leftStart, rightStart, len; while(scanf("%s", input) != EOF) { len = strlen(input); /* tag == 0 : is not a palindrome. * tag == 1 : is a regular palindrome. * tag == 10 : is a mirrored string. * tag == 11 : is a mirrored palindrome. */ tag = 0; middle = len / 2; if(len % 2 == 0) //划分奇、偶串 { leftStart = middle - 1; rightStart = middle; } else { leftStart = middle; rightStart = middle; } if(isPalindrome(input, leftStart, rightStart)) { tag += 1; } if(isMirrored(input, leftStart, rightStart)) { tag += 10; } print(tag); } return (EXIT_SUCCESS); }