演算法競賽入門經典字串推薦題目
阿新 • • 發佈:2019-02-15
題目
UVA 401 Palidromes
分析
- 鏡面字串應關於中間位置鏡面對稱,特別地,若中間位置為一字元則該字元也應自鏡面對稱,所以字串的字元個數的奇偶需要考量.
- 因為
數字0
和字母O可視為一致,因此僅字母O是合法輸入,即不必考慮輸入資料包含數字0
. - 注意格式:每輸出一行資料,應跟隨輸出一空行.
程式碼
#include <stdio.h>
#include <string.h>
int is_palindrome(char* str, int len)
{
int i;
for (i = 0; i < len/2; i++)
if (*(str + i) != *(str + (len-1) - i))
return 0;
return 2;
}
int is_mirrored(char* str, int len)
{
const char* ch = "AEHIJLMOSTUVWXYZ12358";
const char* re = "A3HILJMO2TUVWXY51SEZ8";
int i, j;
for (i = 0; i < len/2+1; i++) {
for (j = 0; j < 21; j++) {
if (*(str + i) == *(ch + j)) {
if (*(str + (len-1) - i) != *(re + j))
return 0;
break;
}
}
if (j == 21) return 0;
}
return 1;
}
int main(void)
{
char str[25];
int len = 0;
while (scanf("%s", str) != EOF) {
printf("%s" , str);
len = strlen(str);
switch (is_palindrome(str, len) | is_mirrored(str, len)) {
case 0: /* 00 */
printf(" -- is not a palindrome.");
break;
case 2: /* 10 */
printf(" -- is a regular palindrome.");
break;
case 1: /* 01 */
printf(" -- is a mirrored string.");
break;
case 3: /* 11 */
printf(" -- is a mirrored palindrome.");
break;
}
printf("\n\n");
}
return 0;
}
UVA 10010 Where’s Waldorf?
分析
- 所需搜尋的模式必定出現且僅出現一次,但大小寫不敏感.
- 先遍歷確定首字母,再進入搜尋,因為模式僅沿八個方向中的固定一個,所以可以滾一遍八方向.
程式碼
#include <stdio.h>
#include <string.h>
int m, n, x, y;
char map[55][55];
int next[8][2] = {{1,1}, {1,0}, {0,1}, {1,-1}, {-1,1}, {-1,0}, {0,-1}, {-1,-1}};
void search(char* s)
{
int pos, nx, ny, i, j, k;
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
if (map[i][j] == s[0])
for (k = 0; k < 8; k++) {
pos = 0;
nx = i;
ny = j;
while (s[pos] && map[nx][ny]==s[pos]) {
nx += next[k][0];
ny += next[k][1];
pos++;
}
if (!s[pos]) { /* base */
x = i;
y = j;
return;
}
}
}
int main(void)
{
int t, i, j, k;
char str[55];
scanf("%d", &t);
while (t--) {
scanf("%d%d", &m, &n);
for (i = 1; i <= m; i++) {
scanf("%s", str);
for (j = 1; j <= n; j++)
map[i][j] = tolower(str[j-1]);
}
scanf("%d", &k);
while (k--) {
scanf("%s", str);
j = strlen(str);
for (i = 1; i <= j; i++)
str[i-1] = tolower(str[i-1]);
search(str);
printf("%d %d\n", x, y);
}
if (t) printf("\n");
}
return 0;
}
UVA 10361 Automatic Poetry
分析
- 字串總分分合合
,而我們卻越恨越深.
程式碼
#include <stdio.h>
#define MAXN 100+10
int main(void)
{
int t, i, j;
char l1[MAXN], l2[MAXN], s[MAXN], s1[MAXN], s2[MAXN], s3[MAXN], s4[MAXN], s5[MAXN];
scanf("%d", &t);
getchar();
while (t--) {
fgets(l1, MAXN, stdin);
fgets(l2, MAXN, stdin);
for (i = 0, j = 0; l1[i] != '<'; i++, j++) s1[j] = l1[i];
s1[j] = '\0';
for (i += 1, j = 0; l1[i] != '>'; i++, j++) s2[j] = l1[i];
s2[j] = '\0';
for (i += 1, j = 0; l1[i] != '<'; i++, j++) s3[j] = l1[i];
s3[j] = '\0';
for (i += 1, j = 0; l1[i] != '>'; i++, j++) s4[j] = l1[i];
s4[j] = '\0';
for (i += 1, j = 0; l1[i] != '\n'; i++, j++) s5[j] = l1[i];
s5[j] = '\0';
for (i = 0, j = 0; l2[i] != '.'; i++, j++) s[j] = l2[i];
s[j] = '\0';
printf("%s%s%s%s%s\n", s1, s2, s3, s4, s5);
printf("%s%s%s%s%s\n", s, s4, s3, s2, s5);
}
return 0;
}
UVA 537 Artificial Intelligence?
分析
- 由於
=
的確定性,用其作關鍵字元,獲得其前一位的物理量,獲得數值(可利用string.h
提供的atof()
方法),再獲得之後的計量單位,對數值進行處理. - 判斷哪一個物理量需要計算,輸出其計算結果.
程式碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 250
int main(void)
{
float data[3], n;
int flag[3]; /* P, U, I */
int t, i, j, k;
char buf[MAXN];
char tmp[10];
scanf("%d", &t);
getchar();
for (i = 0; i < t; i++) {
memset(flag, 0, sizeof(flag));
memset(data, 0, sizeof(data));
fgets(buf, MAXN, stdin);
for (j = 0; j < strlen(buf);) {
/*if (!(flag[0]||flag[1]) || !(flag[1]||flag[2]) || !(flag[0]||flag[2]) )*/
if (buf[j] == '=') {
for (k = 0; (buf[j+1+k] >= '0' && buf[j+1+k] <= '9') || buf[j+1+k] == '.'; k++)
tmp[k] = buf[j+1+k];
tmp[k] = '\0';
n = atof(tmp);
if (buf[j+1+k] == 'm')
n = n * 0.001;
else if (buf[j+1+k] == 'k')
n = n * 1000;
else if (buf[j+1+k] == 'M')
n = n * 1000000;
if (buf[j-1] == 'P') {
data[0] = n;
flag[0] = 1;
} else if (buf[j-1] == 'U') {
data[1] = n;
flag[1] = 1;
} else if (buf[j-1] == 'I') {
data[2] = n;
flag[2] = 1;
}
j += k;
} else {
j++;
}
}
printf("Problem #%d\n", i+1);
for (j = 0; j < 3; j++) {
if (flag[j] == 0) {
if (j == 0) {
printf("P=%.2fW\n", data[1]*data[2]);
} else if (j == 1) {
printf("U=%.2fV\n", data[0]/data[2]);
} else {
printf("I=%.2fA\n", data[0]/data[1]);
}
break;
}
}
if (i != t-1) printf("\n");
}
return 0;
}
UVA 409 Excuses, Excuses!
分析
- 儲存藉口(
excuses
)的關鍵詞用於後面的匹配. - 獲取每一句藉口的每一個單詞,與關鍵詞匹配,並存儲該藉口中關鍵詞的出現次數.
- 注意:輸出關鍵詞出現次數最多的藉口,但可能不止一個.
程式碼
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
int k, e, a[25], max, t = 1, i, j, m, n;
char word[25][25], excuse[25][75], ch[75];
while (scanf("%d%d", &k, &e) != EOF) {
getchar();
for (i = 0; i < k; i++) {
scanf("%s", word[i]);
getchar();
}
memset(a, 0, sizeof(a));
max = 0;
for (i = 0; i < e; i++) {
fgets(excuse[i], 75, stdin);
for (j = 0; j < strlen(excuse[i]);) {
for (m = 0; isalpha(excuse[i][j+m]); m++)
ch[m] = tolower(excuse[i][j+m]);
if (m) {
ch[m] = '\0';
/* printf("catch:%s\n", ch);*/
j += m;
for (n = 0; n < k; n++) {
if (strcmp(ch, word[n]) == 0) {
a[i]++;
break;
}
}
} else {
j++;
}
}
max = max > a[i]? max: a[i];
/*printf("%d\n", a[i]);*/
}
printf("Excuse Set #%d\n", t++);
for (i = 0; i < e; i++)
if (a[i] == max)
printf("%s", excuse[i]);
printf("\n");
}
return 0;
}
UVA 10878 Decode the tape
分析
- 打孔紙帶可能指向二進位制,可以嘗試用二進位制的方式思考,假設打孔表示1,並且得到的數恰又是
ASCII碼
,輸出結果得到驗證,紙帶已解.
程式碼
#include <stdio.h>
#include <string.h>
int main(void)
{
char tape[15];
int i, r;
int f[] = {0, 0, 64, 32, 16, 8, 0, 4, 2, 1, 0};
while (fgets(tape, 15, stdin)) {
r = 0;
for (i = 2; i < 10; i++)
if (tape[i] == 'o')
r += f[i];
if (r != 0) putchar(r);
}
return 0;
}
UVA 10815 Andy’s First Dictionary
分析
- 逐字元清洗,獲得字典.
- 使用類
qsort()
快速排序等方法避免超時.
程式碼
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
char word[27050][250];
int comp(const void* a, const void* b)
{
return strcmp((char*)a, (char*)b);
}
int main(void)
{
char ch;
int i = 0, j = 0;
while ((ch = getchar()) != EOF ) {
if (isalpha(ch)) {
word[i][j++] = tolower(ch);
} else if (j) {
word[i][j] = '\0';
i++;
j = 0;
}
}
qsort(word, i, sizeof(word[0]), comp);
for (j = 0; j < i; j++)
if (strcmp(word[j], word[j+1]))
printf("%s\n", word[j]);
return 0;
}
UVA 644 Immediate Decodability
分析
- 兩兩比較一個
code
是否是另一code
的字首,如果是則說明存在二義性,即不可立即解碼.
程式碼
#include <stdio.h>
#include <string.h>
int is_prefix(const char* a, const char* b)
{
if (strlen(a) > strlen(b))
return is_prefix(b, a);
int i;
for (i = 0; i < strlen(a)-1; i++)
if (*(a+i) != *(b+i))
return 0;
return 1;
}
int main(void)
{
char bit[10][15];
char buf[15];
int t, n = 0, i, j, flag;
for (t = 1; fgets(buf, 15, stdin); ) {
if (buf[0] == '9') {
flag = 0;
for (i = 0; i < n; i++) {
for (j = i+1; j < n; j++) {
if (is_prefix(*(bit+i), *(bit+j))) {
printf("Set %d is not immediately decodable\n", t);
flag = 1;
break;
}
}
if (flag) break;
}
if (!flag) printf("Set %d is immediately decodable\n", t);
n = 0;
t += 1;
} else {
strcpy(bit[n++], buf);
}
}
return 0;
}
UVA 10115 Automatic Editing
分析
- 依次利用給定規則,將字串滾一遍.
- 拼接字串
(disgusting!).
程式碼
#include <stdio.h>
#include <string.h>
int main(void)
{
char fid[15][90], rep[15][90], str[300], tmp[300];
int t, i, j, k, m;
while (scanf("%d", &t) && t) {
getchar();
for (i = 0; i < t; i++) {
fgets(fid[i], 90, stdin);
fgets(rep[i], 90, stdin);
}
fgets(str, 90, stdin);
for (j = 0; j < t; j++) {
for (i = 0; i < strlen(str)-1;) {
for (k = 0; k < strlen(fid[j])-1; k++)
if (str[i+k] != fid[j][k])
break;
if (k == strlen(fid[j])-1) {
memset(tmp, 0, sizeof(tmp));
for (m = 0; m < i; m++) tmp[m] = str[m];
for (m = 0; m < strlen(rep[j])-1; m++) tmp[i+m] = rep[j][m];
for (m = 0; m <= strlen(str) - strlen(fid[j]); m++) tmp[i+strlen(rep[j])-1+m] = str[i+strlen(fid[j])-1+m];
strcpy(str, tmp);
i = 0;
} else
i++;
}
}
printf("%s", str);
}
return 0;
}