1. (2014)计算两个字符串的编辑距离
问题定义
把两个字符串变成相同的三个基本操作定义如下:
分析: 和最长公共子串极为相似,具体为
d p [ i ] [ j ] = { d p [ i − 1 ] [ j − 1 ] s t r 1 [ i ] = s t r 2 [ j ] min { d p [ i − 1 ] [ j − 1 ] + 1 , d p [ i − 1 ] [ j ] + 1 , d p [ i ] [ j − 1 ] + 1 } s t r 1 [ i ] ≠ s t r 2 [ j ] dp[i][j] = \begin{cases} dp[i-1][j-1] & str1[i] = str2[j] \\ \min\{dp[i-1][j-1]+1,dp[i-1][j]+1,dp[i][j-1]+1\} & str1[i] \neq str2[j] \end{cases} dp[i][j]={dp[i−1][j−1]min{dp[i−1][j−1]+1,dp[i−1][j]+1,dp[i][j−1]+1}str1[i]=str2[j]str1[i]=str2[j]
注: str1[i] != str2[j]时,三种情况的解释如下:
初试化条件为: d p [ 0 ] [ 0 ] = 0 , d p [ 0 ] [ j ] ( j ∈ [ 1 , m ] ) = j , d p [ i ] [ 0 ] ( i ∈ [ 1 , n ] ) = i dp[0][0] = 0,dp[0][j] (j \in[1,m]) = j, dp[i][0] (i\in[1,n]) = i dp[0][0]=0,dp[0][j](j∈[1,m])=j,dp[i][0](i∈[1,n])=i
2 . (2015)正方形个数
给出长方形的长和宽,每次从长方形里撕去最大的正方形,输出最后能得到多少正方形
void square_cnt(int l, int w) {
int cnt = 0;
while (l > w) {
l -= w;
cnt++;
if (l < w) swap(l,w);
}
printf("%d", cnt + 1); //l=w(+1)
}
3 . (2015)优先级队列的实现
ADD N P:往队列里加入id为N的优先级为P的任务
NEXT:输出下一个最高优先级的任务的id,如果优先级相同输出id小的任务,若队列中没有任务输出-1
REMOVE N:移除id为N的任务
COUNT:输出队列中的任务数量
分析: 刚学会了priority_queue就拿来用用,但是有个缺陷就是REMOVE时要O(pq.size())的复杂度,不过因为不清楚具体数据量,也不会其它方法,就先这样啦,核心代码如下:
struct process{
int id;
int p;
process(int a = 0, int b = 0) :id(a), p(b) {} //init
};
struct cmp {
bool operator() (process p1, process p2) {
if (p1.p == p2.p) {
return p1.id > p2.id; //优先级相同则id小的在前
}
return p1.p < p2.p; //优先级大的在前
}
};
//priority_queue qi; //后两个参数缺省,优先队列就是大顶堆,队头元素最大
priority_queue, cmp> pq;
4 . (2016) Huffman编码长度
给定一个字符串,求哈夫曼编码的长度
核心步骤如下:
5 . (2014) Hanoi塔
把A 柱上的n 个金片,搬动到C 柱(中间可以使用B 柱),使得搬动的次数最少。输入金片的个数n(1<=n<=64),输出总搬动次数,以及最后100 次搬动。如果搬动次数小于等于100 则全部输出;每个搬动占一行,加上这是第几次搬动的数字和”:”,格式见示例。
输入样例
2
输出样例
3
1:A->B
2:A->C
3:B->C
分析: 不是很明白。。。先贴下非递归的链接,以后抽时间补充
http://blog.sina.com.cn/s/blog_48e3f9cd01000474.html
6 . (2013) 字符串匹配
对于主串M和模式串P,找到P在M中出现的所有子串的第一个字符在P中的位置。P中第一个字符所在的位置为0。首行
的数字表示有多少组字符串。
[输入及示例]
2
ababababa
ababa
aaa
aa
[输出及示例]
0 2 4
0 1
(相邻位置之间用一个空格隔开)
#include
#include
#include //string
using namespace std;
void Solve(string m, string p) {
string m1;
int pos = m.find(p);
int len = m.size();
int pos1;
printf("%d", pos);
//原字符串上截取子串时用另一个变量保存
while (len - pos - 1 >= p.size()) {
m1 = m.substr(pos + 1, len - pos - 1);
pos1 = m1.find(p);
if (pos1 != string::npos) {
pos += (pos1 + 1);
printf(" %d", pos);
}
else break;
}
printf("\n");
}
int main() {
string m, p;
int n;
scanf("%d", &n);
while (n--) {
cin >> m >> p;
Solve(m, p); //至少匹配一个
}
return 0;
}