C++常用函数(刷PAT甲级总结)

判断素数

HDU1059
求一个数字的质因子之积时,只需要考虑小于等于根号n的质因子,但是最后剩下的可能还是个质数,所以要格外考虑下

bool isPrime(int x){
    if(x<=1)
        return false;
    for(int i=2; i<=int(sqrt(x*1.0)); i++){
        if(x % i == 0)
            return false;
    }
    return true;
}

最大公约数gcd 辗转相除法

int gcd(long long a, long long b){
    return b == 0 ? abs(a) : gcd(b, a%b);
}

最小公倍数

int lcm(int a, int b) {
	return a * b / gcd(a, b); 
}

四则运算

https://pintia.cn/problem-sets/994805342720868352/problems/994805378443755520

//定义分子分母
struct fraction{
    ll up, down;
}a, b;

//gcd最简化
fraction reduction(fraction res){
    if(res.down<0){  //保证分母是正数
        res.up = -res.up;
        res.down = -res.down;
    }
    if(res.up == 0)
        res.down = 1;
    else{
        int t = gcd(abs(res.up), abs(res.down));
        res.up /= t;
        res.down /= t;
    }
    return res;
}
//分数加法
fraction add(fraction f1, fraction f2){
    fraction res;
    res.up = f1.up * f2.down + f2.up * f1.down;
    res.down = f1.down * f2.down;
    return reduction(res);
}
//输出形式
void showResult(fraction res){
    res = reduction(res);
    if(res.up<0)
        cout << "(";
    if(res.down == 1)
        cout << res.up;
    else if(abs(res.up) > res.down)
        cout << res.up/res.down << " " << abs(res.up)%res.down << "/" << res.down;
    else
        cout << res.up << "/" << res.down;
    if(res.up<0)
        cout << ")";
}

将n按照d进制逆序

while(n){
    sum = sum * d + n % d;
    n = n / d;
}

结构体的定义

struct record{
    char name[25];
    int month, dd, hh, mm;
    bool status;
}rec[maxn], temp;

排序cmp

bool cmp(record a, record b){
    int s = strcmp(a.name, b.name);
    if(s != 0)
        return s < 0; //优先按照姓名字典序从小到大排序
    else if(a.month != b.month) //按照月份排序
        return a.month < b.month;
    else if(a.dd != b.dd)
        return a.dd < b.dd;
    else if(a.hh != b.hh)
        return a.hh < b.hh;
    else
        return a.mm < b.mm;
}

//比较字符串或者是char数组时,用strcmp
return strcmp(a.id,b.id)<0;

//使用方法
sort(rec, rec+N, cmp);

枚举2^n种情况(熄灯问题)

直到guess()==flase退出枚举

while(guess()){
    press[1][1]++;
    int k=1;
    while(press[1][k] > 1){
        press[1][k] = 0;
        k++;
        press[1][k]++;
    }
}

大整数加法

string add(string s1,string s2)  // 加
{
    int i,j,k,t;
    string sum;
    t=0;
    k=0;
    if(s2.size()>s1.size())
    {
        s1.swap(s2);
        k=1; //标记是否s1,s2交换;保证s2长度不大于s1
    }
    for(i=0;i<s2.size();i++)
    {
        sum+=(s1[s1.size()-1-i]-'0'+s2[s2.size()-1-i]-'0'+t)%10+'0';  //从末位开始逐位做加法,t表示是否进位
        if((s1[s1.size()-1-i]-'0'+s2[s2.size()-1-i]-'0'+t)>=10)
            t=1;
        else t=0;
    }

    if(s1.size()==s2.size() && t==1)
        sum+='1';
    else
    {
        for(j=s1.size()-1-i;j>=0;j--)
        {
            sum+=(s1[j]-'0'+t)%10+'0';
            if(s1[j]-'0'+t>=10)
                t=1;
            else t=0;
        }
        if(t==1)
            sum+='1';
    }
    reverse(sum.begin(),sum.end());
    return sum;
}

大整数减法

string sub(string s1,string s2)   // 减
{
    int flag=0,i;
    if(s1.size()<=s2.size())
    {
        if(s2.size()>s1.size())
            flag=1;
        else
        {
            for(i=0;i<s1.size();i++)
            {
                if(s1[i]>s2[i])
                    break;
                else if(s1[i]<s2[i])
                {
                    flag=1;
                    break;
                }
            }
        }
    }
    //保证s2小于等于s1
    if(flag==1)
        s1.swap(s2);
    string ans;
    reverse(s1.begin(),s1.end());
    reverse(s2.begin(),s2.end());
    for(i=0;i<s1.size();i++)
    {
        if(i>=s2.size())
            s2+='0';
        ans+=s1[i]-s2[i]+'0';
        if(s1[i]<s2[i])
        {
            ans[i]+=10;
            s1[i+1]-=1;
        }
    }
    reverse(ans.begin(),ans.end());
    for(i=0;i<ans.size();i++)
    {
        if(*ans.begin()=='0')ans.erase(ans.begin());
        else break;
    }
    if(flag==1)
        ans.insert(0,"-");
    return ans.size()==0?"0":ans;
}

大整数乘法

string mul(string s1,string s2)    // 乘
{
    int i,j,t;
    vector<int> num1,num2,ans;
    string s;
    //倒过来放算的时候比较方便
    for(i=s1.size()-1;i>=0;i--)
    {
        num1.push_back(s1[i]-'0');
    }
    for(i=s2.size()-1;i>=0;i--)
    {
        num2.push_back(s2[i]-'0');
    }

    //按照平常的计算方式计算
    for(i=0;i<num2.size();i++)
        for(j=0;j<num1.size();j++)
        {
            if(i+j>=ans.size())
                ans.push_back(num1[j]*num2[i]);
            else 
                ans[i+j]+=num1[j]*num2[i];
        }
    
    //解决进位问题
    t=0;
    for(i=0;i<ans.size();i++)
    {
        ans[i]+=t;
        t=ans[i]/10;
        ans[i]%=10;
    }
    if(t!=0)
        ans.push_back(t);
    reverse(ans.begin(),ans.end());
    for(i=0;i<ans.size();i++)
        s+=ans[i]+'0';
    return s;
}

将字符串转化为double,整数转为字符串

string n;
double x = atof(n.c_str())

//整数转为字符串
int n;
string m = to_string(n);

读入未知长度以空格区分的一行数据

//例如 * + 11.0 12.0 + 24.0 35.0
string temp;
while(cin >> temp){
     n[index++] = temp;
     char ch = getchar();//通过getchar()来判断最后输入回车符结束
     if(ch == '\n')
        break;
}

优先队列

队首元素一定是当前队列中优先级最高的那一个

priority_queue<int> q;
priority_queue<int, vector<int>, less<int> > q;
priority_queue<double, vector<double>, greater<double> > q;
//默认最大的最优先,通过改变greater实现数字越小,优先级越高

中缀转为后缀表达式(含!)

string s;
vector<char> sta;
stack<char> temp;
getline(cin, s);
sta.clear();
for(int i=0; i< s.size(); i++){
   if(s[i] == ' ')
       continue;
   if(s[i] == 'V' || s[i] == 'F')
       sta.push_back(s[i]);
   else{
       if(s[i] == '('){
           temp.push(s[i]);
       }
       else if(s[i] == ')'){
           char x = temp.top();
           sta.push_back(x);
           temp.pop();
           temp.pop();
       }
       else if(s[i] == '!'){
           temp.push(s[i]);
       }
       else if(s[i] == '|' || s[i] == '&'){
           if(temp.empty())
               temp.push(s[i]);
           else{
               while(temp.top() == '|' || temp.top() == '&' || temp.top() == '!'){
                   sta.push_back(temp.top());
                   temp.pop();
                   if(temp.empty())
                       break;
               }
               temp.push(s[i]);
           }
       }
   }
}
for(int i=0; i<temp.size(); i++){
   sta.push_back(temp.top());
   temp.pop();
}

KMP

用string存储有时会超时,可用char[]数组代替

//将字符串输入到s中,并且增加s[0]=k,输入从s[1]开始
char s[100];
scanf("%s", s+1);
    s[0] = 'k';
//求输入到数组中的字符串长度
int len = strlen(s);
//nextval
void cal_nextval(string t){
    int i=1, j=0;
    nextval[1] = 0;
    while(i <= t.length()){
        if(j == 0 || t[i] == t[j]){
            i++;
            j++;
            if(t[i] != t[j])
                nextval[i] = j;
            else
                nextval[i] = nextval[j];
        } else
            j = nextval[j];
    }
}

//KMP

int kmp(string s, string t){
    cal_nextval(t);
    int i=1, j=1;
    int c = 0;
    while(i <= s.length() && j <= t.length()){
        if(j==0 || s[i] == t[j]){
            i++;
            j++;
        } else
            j = nextval[j];
        if(j>t.length()){
            c++;
            j=nextval[j];
        }
    }
    return c;
}

kmp next 变形

char s[1005];
char t[1005];
int nextval[1005] = {0};

void get_next(int len_t){
    int i=0, j=-1;
    nextval[0] = -1;
    while(i < len_t){
        if(j == -1 || t[i]==t[j]){
            i++;j++;
            nextval[i] = j;
        } else
            j = nextval[j];
    }
}

int kmp(int len_s, int len_t){
    get_next(len_t);
    int count=0;
    int i=0, j=0;
    while(i < len_s){
        if(j==-1 || s[i] == t[j]){
            i++;j++;
        }
        else
            j=nextval[j];
        if(j>=len_t){
            j=0;
            count++;
        }
    }
    return count;
}

int main(){
    while(cin >> s){
        if(s[0] == '#' && strlen(s) == 1)
            break;
        cin >> t;
        int len_s = strlen(s);
        int len_t = strlen(t);
        cout << kmp(len_s, len_t) << endl;

    }
}

map的使用

map的遍历顺序与输入顺序是不一致的,内部是红黑树机制

map<string, string> m;
m[b] = a; //赋值或者取值
//map初始化
map<int, string>m = {{0,"ling"}, {1,"yi"}}
//迭代
map<string, string>::iterator iter;
for(iter=m.begin(); iter != m.end(); iter++)
	cout << iter->first << " " << iter->second << endl;

//迭代法二
for(auto & it : mp){
    nod temp;
    temp.cardnum = it.first;
    temp.nt = it.second;
    v2.push_back(temp);
}

list的使用

list<int> lit[10005];
//插入
lit[id1].push_back(id2);
//合并两个list
lit[id1].merge(lit[id2]);
//去重,unique只能去重相邻元素
lit[id1].unique();
//list不能按下标取值,只能用迭代器
list<int>::iterator it;
int i=0;
for(it=lit[id1].begin();it!=lit[id1].end();++it)
	cout << *it << endl;

前序和中序构造二叉链表

struct node{
    int data;
    node *lc, *rc;
}*N;

node * PreInCreate(int prei, int prej, int ini, int inj){
    node *root = new node;
    root->data = pre[prei];
//    cout << root->data << " ";
    int i;
    for(i=ini; in[i]!=root->data; i++);
    int llen = i-ini;
    int rlen = inj-i;
    if(llen)
        root->lc = PreInCreate(prei+1, prei+llen, ini, i-1);
    else
        root->lc = NULL;
    if(rlen)
        root->rc = PreInCreate(prej+i-inj+1, prej, i+1, inj);
    else
        root->rc = NULL;
    return root;
}

node *TT = new node;
TT = PreInCreate(1, k, 1, k);

数组置为inf

#define inf 0x3f3f3f
//int e[1000][1000], dis[1000];
fill(e[0], e[0] + 510 * 510, inf);
fill(dis, dis + 510, inf);
memset(dis, 0, sizeof(dis));

大整数正反相加

如s=1234567
即求 1234567+7654321

Cin Cout 超时

一、使用scanf, printf代替

char name[10];
scanf("%s", name);
//可以直接strcmp(name, "xxxx")==0判断

实在是要用string
!!!

node.name.resize(10);
scanf("%s", &node.name[0]);//这样输入会自动在不足resize的位置以“\0”填充,所以不能直接跟给定的“xxx”进行==比较
printf("%s", node.name.c_str());
//加上.c_str()之后,会把后面的"\0"去掉

!!!
char[]数组和string比较字符串时有区别
char[]
return (strcmp(a.name, b.name) < 0);
string
return a.name < b.name;

vector初始化

vector<int>v(n);
//这样就可以直接给v[i]赋值,如果不初始化(不加(n))只能push_back

关于string
可以用s.substr(1,3)代表子串,从1开始的3位

二、直接cin >> node[i].ch,也可能会超时,先cin到临时变量,再存到node里面去

三、map<string, vector > stu;
👆比👇快
map<string, int> stu;
vector course;
放在

struct stu{
    char id[8], name[9];
    int score;
}student;
scanf("%s%s%d", student.id, student.name, &student.score);

unordered_map比map快

未在map里的东西,直接用时等于0

图————求两点间的最短距离,最短距离一致则找最小花费 dijskra+dfs模板

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f

//图————求两点间的最短距离,最短距离一致找最小花费
//dijskra+dfs, dijskra解决最短路径,dfs解决花费最少问题

//e代表两点间距离,dis代表start到该点的最短路径,cost代表两点间花费
int e[510][510], dis[510], cost[510][510];
int n, m, s, d;
//pre代表从起点到该点的路径
vector<int> pre[510];
//path代表最终路径,temppath是临时变量
vector<int> path, temppath;
//visit代表该点是否被访问过
bool visit[510];
//mincost代表最小花费
int mincost = inf;

void dfs(int v){
    temppath.push_back(v);
    //更新路径,找到花费最少的
    if(v == s){
        int tempcost = 0;
        for(int i=temppath.size()-1; i>0; i--){
            int id=temppath[i], nextid=temppath[i-1];
            tempcost += cost[id][nextid];
        }
        if(tempcost < mincost){
            mincost = tempcost;
            path = temppath;
        }
        //
        temppath.pop_back();
        return;
    }
    for(int i=0; i<pre[v].size(); i++)
        dfs(pre[v][i]);
    temppath.pop_back();
}


int main(){
    fill(e[0], e[0]+510*510, inf);
    fill(dis, dis+510, inf);
    cin >> n >> m >> s >> d;
    for(int i=0; i<m; i++){
        int a, b;
        cin >> a >> b;
        cin >> e[a][b];
        e[b][a] = e[a][b];
        cin >> cost[a][b];
        cost[b][a] = cost[a][b];
    }
    pre[s].push_back(s);
    dis[s] = 0;
    //设置dis[s]=0,从出发点开始算
    for(int i=0; i<n; i++){
        //u代表当前最近的点
        int u=-1, mmin=inf;
        for(int j=0; j<n; j++){
            //从所有没被访问过的点中找出距离最近的点加入集合中
            if(visit[j] == false && dis[j] < mmin){
                u=j;
                mmin = dis[j];
            }
        }
        //没有多余连通的点
        if(u==-1)
            break;
        visit[u] = true;
        //以u为起始,更新整个未访问过的集合,pre存放与该节点最近相连的1个或者n个节点
        for(int v=0; v<n; v++){
            if(visit[v]==false && e[u][v]!=inf){
                if(dis[v] > dis[u]+e[u][v]){
                    dis[v] = dis[u]+e[u][v];
                    pre[v].clear();
                    pre[v].push_back(u);
                }
                else if(dis[v] == dis[u]+e[u][v]){
                    pre[v].push_back(u);
                }
            }
        }
    }
    dfs(d);
    for(int i=path.size()-1; i>=0; i--)
        cout << path[i] << " ";
    cout << dis[d] << " " << mincost << endl;
}

将数组置为inf

int e[510][510];
fill(e[0], e[0]+510*510, inf);

int dis[510];
fill(e, e+510, inf);

将string全部映射为int

PAT 1034 Head of a Gang
dfs求连通域个数,图的节点是string类型,需要转化为int类型

map<int , string> intTostring;
map<string, int> stringToint;
//name1已有对应的string
if(stringToint.find(name1) != stringToint.end())
	id1 = stringToint[name1];
//第一次出现的string,找一个新的数字跟他对应
else{
    stringToint[name1] = now_person;
    intTostring[now_person] = name1;
    id1 = now_person;
    now_person++;
}

二分查找(nlogn)

PAT 1044 Shopping in Mars
递增数组,从p开始查找不小于k且最接近k的数字区间段存入res
总长度为n
数组sum

void search(int p){
    int start = p, end = n;
    while(start < end){
        int mid = (start+end)/2;
        if(sum[mid] - sum[p-1] >= k)
            end = mid;
        else
            start = mid+1;
    }
    int temp = sum[start] - sum[p-1];
    if(temp >= k && temp <= mmax){
        if(temp < mmax){
            mmax = temp;
            res.clear();
        }
        res.push_back(p);
        res.push_back(start);
    }

}

有回溯的dfs

寻找符合条件的多条路径,此时需要回溯
PAT1053 Path of Equal Weight (30 分)
自己一次过做出来的30分题,还有点小开心的!

//p为路径,ss为路径上的权重值,visit为是否访问
void dfs(int t){
    visit[t] = 1;
    ss += weight[t];
    p.push_back(t);
    if(node[t].size() == 0 && ss == s){
        vector<int> temp;
        for(int k=0; k<p.size(); k++){
            temp.push_back(weight[p[k]]);
        }
        final.push_back(temp);
        //找到一条路径,以下条件需要恢复环境
        p.pop_back();
        ss -= weight[t];
        visit[t] = 0;
        return;
    }

    for(int i=0; i<node[t].size(); i++){
        if(visit[node[t][i]] == 0)
            dfs(node[t][i]);
    }
    //这些条件后面的路径还会用到,所有需要恢复环境
    visit[t] = 0;
    ss -= weight[t];
    p.pop_back();
}

set和multiset

set的含义是集合,它是一个有序的容器,里面的元素都是排序好的,支持插入,删除,查找等操作,就像一个集合一样。所有的操作的都是严格在logn时间之内完成,效率非常高。 set和multiset的区别是:set插入的元素不能相同,但是multiset可以相同

set中find和count的时间复杂度都为logn
求两个数组的交集数字个数

set 迭代器输出用 *iter
默认按照递增的顺序排列

int nc = 0;
for(auto it = st[id1].begin();it != st[id1].end();it++){
   if(st[id2].find(*it) != st[id2].end()) 
       nc++;//使用find,去第二个数列中查找该数出现过没有
} 

求某数化为二进制后有多少位为1

int FF(int i){
    int x=0;
    while(i){
        if(i & 1){
            x++;
        }
        i >>= 1;
    }
    return x;
}

中序序列==>顺序输出

将有序序列变为完全二叉树的中序序列存储

int num[2001], res[2001];
int n, k=0;
//num存储现有的有序序列,res存储中序序列,n=size
void inorder(int t){
    if(t >= n)
        return;
    inorder(t*2+1);
    res[t] = num[k++];
    inorder(t*2+2);
}
//调用
inorder(0);

使序列有序的最少交换次数

n = 数列元素个数 - 循环节个数

https://blog.csdn.net/lfb637/article/details/86653121

仅允许在相邻两元素间交换,求最少交换次数
即求逆序对==>归并排序算法可求

https://blog.csdn.net/lfb637/article/details/78309507

atoi stoi

将数字字符串转为int
atoi不会做范围检查,stoi会做范围检查,超出int范围报错runtime error
stoi(s1);
atoi(s1.c_str());

往字符串中插入0
s.insert(0, 4-s.length(), ‘0’);

边界条件

1、字符串比较时考虑字符串的长度

易忽略的点

1、C++中int和long long特别容易被忽略的点,在做乘法的时候即使单个变量在int范围内,如果乘积超了int,也需要将乘数定义为longlong 否则会出错
long double------>printf("%.2Lf", x)
2、vector可以直接使用=号来判断两个数组是否相同
3、数据为10^9时,inf要定义成0x3f3f3f3f,否则真的会死掉!
4、实在过不去,把数组开大点
5、int 10位,2^32次-1;long long 19位,2的63次-1
6、NULL——int类型默认为0,bool类型默认为false
7、int visit[205] = {0};像这样的定义必须在循环里重新赋值为0,用fill或者for循环,否则编译器不同可能会报错
8、二维数组开到10的5次乘10的5次会内存超限,用vector,map等巧妙化解
9、有关树的题目,左右子树要乘2,所以数组大小要开到2倍以上

dfs、bfs基础模板

void dfs(int u, int l){
    visit[u] = 1;
    for(int i=0; i<v[u].size(); i++){
        if(visit[v[u][i]] == 0)
            dfs(v[u][i], l+1);
    }
}

三维数组求连通域——bfs

https://blog.csdn.net/qq_34649947/article/details/81213275

//表示三个方向
int xx[6] = {0,0,0,0,-1,1};
int yy[6] = {0,0,-1,1,0,0};
int zz[6] = {-1,1,0,0,0,0};
struct node{
    int x, y, z;
};
queue<node> q;

排序

当题目中涉及到插入排序,归并排序等,不需要真的去实现,用sort就可以

并查集!!

https://blog.csdn.net/zjy_code/article/details/80634149

例题:PAT 1107 Social Clusters
记录每个节点的父亲节点是哪个节点,是否属于一个门派

//初始化:初始的时候每个结点各自为一个集合,father[i]表示结点 i 的父亲结点,如果 father[i]=i,我们认为这个结点是当前集合根结点。
void init() {
    for (int i = 0; i < n; ++i) {
        father[i] = i;
    }
}
//查找:查找结点所在集合的根结点,结点 x 的根结点必然也是其父亲结点的根结点。
int get(int x) {
    if (father[x] == x) { // x 结点就是根结点
        return x;
    }
    return father[x] = get(father[x]); // 返回父结点的根结点,并另当前结点父结点直接为根结点
}
//合并:将两个元素所在的集合合并在一起,通常来说,合并之前先判断两个元素是否属于同一集合。
void merge(int x, int y) {
    x = get(x);
    y = get(y);
    if (x != y) { // 不在同一个集合
        father[y] = x;
    }
}

调整大顶堆

把数组中最大的数字调整到最上面,并且把下面的恢复成大顶堆的样子
因为本来就是大顶堆,只是第一个数字变了,所以影响的只是单路上的数字

//法一
void downAdjust(vector<int> &b, int low, int high) {
    int i = 1, j = i * 2;
    while(j <= high) {
        if(j + 1 <= high && b[j] < b[j + 1]) j = j + 1;
        if (b[i] >= b[j]) break;
        swap(b[i], b[j]);
        i = j; j = i * 2;
    }
}

//法2
//将元素k为根的子树进行调整
void HeadAdjust(int a[], int k, int len){
    a[0] = a[k];
    for(int i=2*k; i<=len; i*=2){
        if(i<len && a[i]<a[i+1])
            i++;
        if(a[0] >= a[i])
            break;
        else{
            a[k] = a[i];
            k=i;
        }
    }
    a[k] = a[0];
}
//构建大顶堆
void BUildmaxHeap(int a[], int len){
    for(int i=len/2; i>0; i--)
        HeadAdjust(a, i, len);
}

//堆排序
void HeapSort(int a[], int len){
	BUildmaxHeap(a, len);
	for(int i=len; i>1; i--){
		swap(a[i], a[1]); //输出堆顶元素(和堆底元素交换)
		HeadAdjust(a, 1, i-1); //调整,把剩余的i-1个元素整理成堆
	}
}

判断输入是否符合规定小数要求

PAT 1108 Finding Average

//要求判断输入是否为保留两位的小数
double temp;
char a[50], b[50];
scanf("%s", a);
sscanf(a,"%lf",&temp); //把a的值以double格式赋给temp。如果输入的不是数字,temp会继续保留之前的数字
sprintf(b,"%.2f",temp);//temp按%.2f写到b
//比较a和b是否一致即可

平衡二叉树

总结模版如下

https://blog.csdn.net/PickCake/article/details/116133191

The lowest common ancestor (LCA)最近公共祖先

1151 LCA in a Binary Tree (30 分)
不需要建树,一般性建树都会超时,或者段错误
一般会给定先序遍历和中序遍历序列
已知某个树的根结点,若a和b在根结点的左边,则a和b的最近公共祖先在当前子树根结点的左子树寻找,如果a和b在当前子树根结点的两边,在当前子树的根结点就是a和b的最近公共祖先,如果a和b在当前子树根结点的右边,则a和b的最近公共祖先就在当前子树的右子树寻找。中序加先序可以唯一确定一棵树,在不构建树的情况下,在每一层的递归中,可以得到树的根结点,在此时并入lca算法可以确定两个结点的公共祖先~

void lca(int inl, int inr, int prel, int a, int b){
    if(inl > inr)
        return;
    int inRoot = pos[pre[prel]], ain = pos[a], bin = pos[b];
    if(ain < inRoot && bin < inRoot)
        lca(inl, inRoot-1, prel+1, a, b);
    else if((ain < inRoot && bin > inRoot) || (ain > inRoot && bin < inRoot))
        printf("LCA of %d and %d is %d.\n", a, b, in[inRoot]);
    else if(ain > inRoot && bin > inRoot)
        lca(inRoot+1, inr, prel+1+(inRoot-inl), a, b);
    else if(ain == inRoot)
        printf("%d is an ancestor of %d.\n", a, b);
    else if (bin == inRoot)
        printf("%d is an ancestor of %d.\n", b, a);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值