C
题意
给定n个由0 1 2 3 4组成的可能含前导0的字符串,问将这些字符串按照一定次序拼接起来得到的字典序最小的串是哪个?
思路
直接写一个cmp函数进行排序,排序方式就是 串1+串2 小于 串2+串1的话,串1在串2前面, 否则,串2在串1前面。注意传入参数要传指针,否则会超时。
代码
#include <iostream>
#include <algorithm>
#include <vector>
#include<string>
using namespace std;
bool cmp(string &a, string &b)
{
string res1 = a + b;
string res2 = b + a;
if(res1 < res2) return true;
else return false;
}
string ss[2000100];
int n;
int main()
{
cin>>n;
for(int i=0; i<n; i++) cin>>ss[i];
sort(ss, ss+n, cmp);
for(int i=0; i<n; i++) cout<<ss[i];
return 0;
}
A
题意
给定两颗树A和B,对于每棵树,结点都是编号1-n,每个结点有一个权值,并且编号1是根节点,然后给定再给定一个序列ai, 问有几个ai满足:删除这个ai, 其它剩下的ai的最近公共祖先结点的权值A树大于B树。
思路
分类讨论,两大类。
第一类,所有ai的最低公共祖先是a序列中的其中一个假设为a1。
1.当a1引出的含ai的子树数量为1时,如果当前要删的是a1自身,那么直接暴力算一遍剩下结点的最低公共祖先,如果删的不是a1自身,剩下的ai最低公共祖先一定还是a1。
2.当a1引出的含ai的子树数量大于等于2时,无论删哪一个ai,最低公共祖先还是a1。
第二类,所有ai的最低公共祖先不是a序列中的一个。
1.当公共祖先引出的含ai的子树数量为1时,显然公共祖先可以不是它,这种情况不存在。
2.当公共祖先引出的含ai的子树数量为2时,预先求出这两个子树里分别包含的ai的数量,找到两个子树中只包含1个ai的情况(不一定有,没有这种情况则更好),记录这个ai,当要删除这个ai的时候,暴力求一遍剩下子树的最低公共祖先,删除其它ai时公共祖先不变。
3.当公共祖先引出的含ai的子树数量大于2时,删除任意一个ai,公共祖先不变。
所以总结一下真正要重新计算公共祖先的情况只有两种:
1.所有ai的最低公共祖先是a序列中的其中一个时,并且公共祖先引出的包含ai的子树数量为1,并且要删的就是公共祖先自身。
2.所有ai的最低公共祖先不是a序列其中一个,并且公共祖先引出的包含ai的子树数量为2,并且要删除的ai所在的那颗子树中只有ai一个属于a序列。
这两种情况求最低公共祖先的方法都是暴力求剩余ai的最低公共祖先。其它情况公共祖先仍然是所有ai的最低公共祖先。
代码
写好再发