刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 1(String)

第一题:401 - Palindromes

UVA : http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=96&page=show_problem&problem=342

解题思路:此题很水,只要把 mirrored string 类的对应关系搞对,基本就可以了! 但是细节要注意,首先只有一个元素的时候需要单独判断,一个字符是回文串,是不是 mirrored string 则需要判断,另外最后输出中间隔了一行!

解题代码:

 // File Name: 刘汝佳-基础/part2/Palindromes/401.cpp
// Author: sheng
// Created Time: 2013年07月20日 星期六 23时37分45秒 #include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std; const int max_n = ;
const int max_f = ; int main ()
{
bool mir[max_f][max_f];
char ch[max_n];
memset (mir, false, sizeof (mir));
mir['A']['A'] = true;
mir['E'][''] = mir['']['E'] = true;
mir['H']['H'] = true;
mir['I']['I'] = ;
mir['J']['L'] = mir['L']['J'] = ;
mir['M']['M'] = ;
mir['O']['O'] = ;
mir['S'][''] = mir['']['S'] = ;
for (int i = 'T'; i <= 'Y'; i ++)
mir[i][i] = ;
mir['Z'][''] = mir['']['Z'] = ;
mir[''][''] = ;
mir[''][''] = ;
while (~scanf ("%s", ch))
{
bool ms = true, ps = true;
int len = strlen (ch);
// cout << len << endl;
if (len == && (!mir[ch[]][ch[]]))
ms = false;
for (int i = ; i < len/; i ++)
{
if ( ch[i] != ch[len--i] )
ps = false;
if (!mir[ch[i]][ch[len--i]])
ms = false;
if ((!ms) && (!ps))
break;
}
if (ms && ps)
cout << ch << " -- is a mirrored palindrome.\n\n";
else if (ms)
cout << ch << " -- is a mirrored string.\n\n";
else if (ps)
cout << ch << " -- is a regular palindrome.\n\n";
else cout << ch << " -- is not a palindrome.\n\n";
}
return ;
}

第二题:10010 - Where's Waldorf?

UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=951

解题思路:因为数据范围很小所以可以暴力搜索,总共八个方向,只要有一个方向可以组成当前单词就标记此开始点并跳出,寻找下一个单词!

水题一道,却花了一下午的时间,英语差是一方面,最不该就是使用了goto,害得程序陷入死循环,而我却在没有bug的地方找死循环的原因找了一下午,哎!还需使劲练习啊!

解题代码:

 // File Name    :刘汝佳-基础/part2/10010 - Where's Waldorf?
// Author :Freetion
// Created Time :2013年07月22日 星期一 14时32分18秒 #include <string.h>
#include <stdio.h> char map[][];
bool tag[][];
int T;
int n, m, k, q;
char ser[][];
int len; struct CUN
{
int x, y;
}cun[]; const int alt_x[] = {-, -, , , , , -, };
const int alt_y[] = {-, , -, , -, , , }; int serch(int x, int y, int l)
{
for (int i = ; i < ; i ++)//八个方向
{
int xx = x + alt_x[i];
int yy = y + alt_y[i];
l = ;
while (l < len && xx > && xx <= n && yy > && yy <= m)//向一个方向找
{
int temp_x = xx + alt_x[i];
int temp_y = yy + alt_y[i];
if (ser[q][l] == map[xx][yy])
{
l ++;
xx = temp_x;
yy = temp_y;
}
else break;
}
if (l == len)
return ;//找到返回1
}
return ;//没有返回0
} void init()
{
for (int i = ; i <= n; i ++)
{
for (int j = ; j <= m; j ++)
{
char ch;
scanf ("%c", &ch);
if (ch <= 'Z')
ch = ch - 'A' + 'a';
map[i][j] = ch;
}
map[i][m+] = '\0';
getchar();
}
/*
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j ++)
printf("%c", map[i][j]);
printf("\n");
}
*/
scanf ("%d", &k);
getchar();
int len;
char ch[];
for (int i = ; i <= k; i ++)
{
scanf ("%s", ch);
len = strlen(ch);
for (int j = ; j < len; j ++)
{
if (ch[j] <= 'Z')
ch[j] = ch[j] - 'A' + 'a';
}
strcpy(ser[i], ch);
ser[i][len] = '\0';
}
/*
for (int i = 1; i <= k; i ++)
printf("len = %d %s\n", strlen(ser[i]), ser[i]);
*/
} int main ()
{
scanf ("%d", &T);
while (T--)
{
scanf ("%d%d", &n, &m);
getchar();
init();
for (q = ; q <= k; q ++)//就是在这里使用了goto导致q一直为1
{
int tag = ;
len = strlen(ser[q]);
char ch = ser[q][];
for (int i = ; i <= n; i ++)
{
for (int j = ; j <= m; j ++)
{
if (ch == map[i][j])
if (serch(i, j, ))
{
cun[q] = (CUN){i, j};
tag = ;
}
if (tag)
break;
}
if (tag)
break;
}
}
for (int i = ; i <= k; i ++)
printf ("%d %d\n", cun[i].x, cun[i].y);
if (T)
printf ("\n");
}
return ;
}

第三题:10361 - Automatic Poetry

UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1302

解题思路:水题一道!

解题代码:

 // File Name    :刘汝佳-基础/part2/10361 - Automatic Poetry
// Author :Freetion
// Created Time :2013年07月22日 星期一 20时10分53秒 #include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
//#define LOCAL
using namespace std; const int max_l = ;
char str1[max_l], str2[max_l], str3[max_l], str4[max_l], str5[max_l], str6[max_l]; int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
int n, num1, num2, num3, num4;
while (~scanf("%d", &n))
{
getchar();
for (int i = ; i < n; i ++)
{
gets(str1);
gets(str2);
int len1 = strlen(str1);
int tag = ;
num1 = num2 = num3 = num4 = ;
for (int j = ; j < len1; j ++)
{
if (str1[j] != '<' && str1[j] != '>')
printf ("%c", str1[j]);
else if (str1[j] == '<')
tag ++;
else if (str1[j] == '>')
tag ++;
if (tag == )
str3[num1++] = str1[j];
else if (tag == )
str5[num3++] = str1[j];
else if (tag == )
str4[num2++] = str1[j];
else if (tag == )
str6[num4++] = str1[j]; }
printf("\n");
int len2 = strlen(str2);
for (int j = ; j < len2-; j ++)
printf ("%c", str2[j]);
for (int j = ; j < num2; j ++)
printf("%c", str4[j]);
for (int j = ; j < num3; j ++)
printf ("%c", str5[j]);
for (int j = ; j < num1; j ++)
printf ("%c", str3[j]);
for (int j = ; j < num4; j ++)
printf ("%c", str6[j]);
printf ("\n"); } }
return ;
}

第四题:537 - Artificial Intelligence?

UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=478

解题思路:按关键字将数据提取出来即可,水题!还有,输出是每个案列后都会有一个空行,这里wa三次! UVA为什么没有PE呢?

解题代码:好吧,可能太长,有点凌乱!

 // File Name    :刘汝佳-基础/part2/537 - Artificial Intelligence?
// Author :Freetion
// Created Time :2013年07月22日 星期一 22时25分10秒 #include <stdio.h>
#include <string.h> const int max_l = ;
char phy[max_l]; int main()
{
int t, T;
scanf ("%d", &t);
T = t;
getchar();
double U, I, P;
int tag_u = , tag_i = , tag_p = ;
while(t--)
{
gets(phy);
int len = strlen(phy);
U = I = P = ;
for (int i = ; i < len; i ++)
{
if (phy[i] == 'U' && phy[++i] == '=')
{
tag_u = ;
int tag = ;
int tm;
i ++;
while(phy[i] == '.' || (phy[i] >= '' && phy[i] <= ''))
{
if (phy[i] == '.')
{
tm = ;
tag = ;
i ++;
}
if (tag)
U = U* + phy[i] - '';
else
{
U = U + (phy[i] - '')*1.0/tm;
tm *= ;
}
i ++;
}
if (phy[i] == 'm')
U = U/;
else if (phy[i] == 'k')
U = U*;
else if (phy[i] == 'M')
U = U**;
}
if (phy[i] == 'I' && phy[++i] == '=')
{
tag_i = ;
int tag = ;
int tm;
i ++;
while(phy[i] == '.' || (phy[i] >= '' && phy[i] <= ''))
{
if (phy[i] == '.')
{
tm = ;
tag = ;
i ++;
}
if (tag)
I = I* + phy[i] - '';
else
{
I = I + (phy[i] - '')*1.0/tm;
tm *= ;
}
i ++;
}
if (phy[i] == 'm')
I = I/;
else if (phy[i] == 'k')
I = I*;
else if (phy[i] == 'M')
I = I**;
}
if (phy[i] == 'P' && phy[++i] == '=')
{
tag_p = ;
int tag = ;
int tm;
i ++;
while(phy[i] == '.' || (phy[i] >= '' && phy[i] <= ''))
{
if (phy[i] == '.')
{
tm = ;
tag = ;
i ++;
}
if (tag)
P = P* + phy[i] - '';
else
{
P = P + (phy[i] - '')*1.0/tm;
tm *= ;
}
i ++;
}
if (phy[i] == 'm')
P = P/;
else if (phy[i] == 'k')
P = P*;
else if (phy[i] == 'M')
P = P**;
}
if (tag_p && tag_u)
break;
if (tag_u && tag_i)
break;
if (tag_p && tag_i)
break; }
printf ("Problem #%d\n", T - t);
if (tag_u && tag_i)
{
tag_u = tag_i = ;
printf ("P=%.2fW\n", U*I);
}
else if (tag_u && tag_p)
{
tag_u = tag_p = ;
printf("I=%.2fA\n", P/U);
}
else
{
printf("U=%.2fV\n", P/I);
tag_i = tag_p = ;
}
//if (t)
printf ("\n");
}
return ;
}

第五题:409 - Excuses, Excuses!

UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=96&page=show_problem&problem=350

解题思路:暴力搜素即可,但须注意判断条件。

解题代码:

 #include <iostream>
#include <stdio.h>
#include <map>
#include <algorithm>
#include <string.h>
using namespace std;
//#define LOCAL struct SENT
{
int sign, num;
bool operator < (const SENT s) const
{
if (num == s.num)
return sign < s.sign;
return num > s.num;
}
}sen[]; int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
char key[][], sent[][];
int n, m, T = ;
while (~scanf("%d%d", &n, &m))
{
getchar();
for (int i = ; i < n; i++)
{
scanf ("%s", key[i]);
getchar();
int len = strlen(key[i]);
for (int j = ; j < len; j ++)
{
if (key[i][j] <= 'Z')
key[i][j] = key[i][j] - 'A' + 'a';
}
}
bool tag[];
for (int i = ; i < m; i ++)
{
memset(tag, true, sizeof(tag));
sen[i].num = ;
sen[i].sign = i;
gets(sent[i]);
// puts(sent[i]);
int len = strlen(sent[i]);
for (int j = ; j < len; j ++)
{
if (j == || ((sent[i][j-] > 'Z' || sent[i][j-] < 'A') && (sent[i][j-] < 'a' || sent[i][j-] > 'z')))
{//不能仅用空格作为判断条件
for (int k = ; k < n; k ++)
{
if ((key[k][] == sent[i][j] || key[k][] == sent[i][j]-'A'+'a') && tag[k])
{
int len_k;
int l;
len_k = strlen(key[k]);
for (l = ; l < len_k; l ++)
{
if (j+l < len && key[k][l] != sent[i][j+l] && key[k][l] != sent[i][j+l]-'A'+'a')
break;
}
if (l == len_k)
{
tag[k] = false;
sen[i].num ++;
j = j+l;
}
}
}
}
}
}
sort(sen, sen+m);
printf("Excuse Set #%d\n", ++T);
for (int i = ; i < m; i ++)
if (sen[i].num == sen[].num)
puts(sent[sen[i].sign]);
puts("");
}
return ;
}

第六题:10878 - Decode the tape

UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=96&page=show_problem&problem=1819

解题思路:找出输入字符与ASCII码的关系就可输出,这里以output打印出 A 作介绍:对应的字符串:

|   o       .     o |

这里列出打印 A 字符的依据,并标上列数, A 字符的ASCII码值为 65 而 65 = 2(10 -4) + 2(10 - 10) 所以打印 A字符,其余字符也是如此计算!

解题代码:

 #include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
//#define LOCAL
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
char ch;
int tag = ;
while ()
{
int s = ;
for (int i = ; i < ; i++)
{
scanf ("%c", &ch);
if (ch == '_')
tag ++;
if (ch == 'o')
{
if (i < )
s += pow(, -i);
else s += pow(, - i);
}
}
getchar();
if (s)
printf("%c", s);
if (tag == )
break;
}
}

第七题:10815 - Andy's First Dictionary

uva:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1756

解题思路:输入字符串,找出所有单词,找过过程中,判断是否保存过,保存过就抛弃,没有则保存,并标记已保存,然后排序输出就可。

解题代码:

 #include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
using namespace std; #define LOCAL #ifdef WINDOWS
#define LL __int64
#define LLD "%I64d"
#else
#define LL long long
#define LLD "%lld"
#endif int main()
{ #ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif map <string, int> word;
string str[], tm1_str, tm2_str;
int cun = ;
while (cin >> tm1_str)
{
int len = tm1_str.length(); for (int i = ; i < len; i ++)
{
tm2_str.clear();
while((tm1_str[i] <= 'Z' && tm1_str[i] >= 'A') || (tm1_str[i] <= 'z' && tm1_str[i] >= 'a'))
{
if (tm1_str[i] <= 'Z')
tm2_str += (tm1_str[i] - 'A' + 'a');
else tm2_str += tm1_str[i];
i ++;
if (i >= len)
break;
}
if (!tm2_str.empty())
{
if (word[tm2_str] == )
{
str[cun++] = tm2_str;
word[tm2_str] = ;
}
}
} }
sort(str, str+cun);
for (int i = ; i < cun; i ++)
cout << str[i] << endl;
return ;
}

第八题:644 - Immediate Decodability

UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=585

解题思路:先按字典序或字符串长短排个序,然后就挨个找就可以了,字典序也可以是因为比如0000,01后者肯定不是前者的前缀,至于00, 000这一类就需要进行判断!

解题代码:

 #include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
using namespace std; //#define LOCAL //Please annotate this line when you submit #ifdef WINDOWS
#define LL __int64
#define LLD "%I64d"
#else
#define LL long long
#define LLD "%lld"
#endif string str, str1[];
map <string, bool> IM; int solve(int cun)
{
int tag = ;
sort(str1, str1+cun);
for (int i = ; i < cun && tag; i ++)
{
string temp;
temp.clear();
int len = str1[i].length();
for (int j = ; j < len && tag; j ++)
{
temp += str1[i][j];
if (IM[temp])
{
tag = ;
break;
}
}
IM[str1[i]] = ;
str1[i].clear();
}
return tag;
} int main()
{ #ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int T = ;
bool tag = ;
int cun = ;
while (cin>>str)
{
if (str[] == '')
{
tag = solve(cun);
if (tag)
printf("Set %d is immediately decodable\n", ++T);
else printf("Set %d is not immediately decodable\n", ++T);
tag = ;
IM.clear();
cun = ;
}
else
str1[cun ++] = str;
}
return ;
}

第九题:10115 - Automatic Editing

UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1056

解题思路:字符串匹配与替换,水题

解题代码:

 #include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
using namespace std; //#define LOCAL //Please annotate this line when you submit #ifdef WINDOWS
#define LL __int64
#define LLD "%I64d"
#else
#define LL long long
#define LLD "%lld"
#endif const int max_n = ; int n;
char rep[max_n][max_n], by[max_n][max_n];
char str[][max_n]; int init()
{
if(~scanf ("%d", &n) && n)
{
getchar();
for (int i = ; i < n; i++)
{
gets(rep[i]);
gets(by[i]);
}
gets(str[]);
// puts(str[0]);
return ;
}
return ;
} int solve()
{
int pos = ;
for (int i = ; i < n; i ++)
{
int len = strlen(str[pos]);
for(int j = ; j < len; j ++)
{
if(str[pos][j] == rep[i][])
{
int k;
int tm_len = strlen(rep[i]);
for (k = ; k < tm_len && j+k < len; k ++)
{
if (str[pos][j+k] != rep[i][k])
break;
}
if (tm_len == k)
{
int cun = ;
for (int r = ; r < len; r ++)
{
if (r != j)
str[pos^][cun++] = str[pos][r];
else
{
int by_len = strlen(by[i]);
for(int l = ; l < by_len; l ++)
str[pos^][cun++] = by[i][l];
r = j + tm_len - ;
}
}
str[pos^][cun] = '\0';
j = ;
len = strlen(str[pos^]);
pos ^= ;
}
}
}
}
return pos;
} int main()
{ #ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
while(init())
{
int pos = solve();
puts(str[pos]);
}
return ;
}

上一篇:刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 3(Sorting/Searching)


下一篇:DEV设计之自动流水号,DEV专家解答,自己折腾了半天也没有搞定,怪英文不好