answer

DS 1、算法的复杂度

1111111

#include<stdio.h>
int main(void){
	int K,i;
	scanf("%d",&K);//输入第1行给出正整数K(≤100000)
	int A[100001];//定义数组来存放整数
	int ThisSum,MaxSum;
	ThisSum=MaxSum=0;
	for(i=0;i<K;i++){
		scanf("%d",&A[i]);
		ThisSum+=A[i];
		if(ThisSum>MaxSum)
		MaxSum=ThisSum;
		else if(ThisSum<0) //如果序列中所有整数皆为负数,则输出0
		ThisSum=0;
}
printf("%d",MaxSum);  //输出最大子列和

}

在这里插入图片描述


```c
#include<stdio.h>
int main()
{
    int n,sum=0,tmp=1;
    scanf("%d",&n);
    if(n>=25)        //当n>=24时,后面的数据都是一样的
    {
        printf("940313\n");
        return 0; 
    }
    for(int i=1;i<=n;i++)
    {
       tmp=(tmp*(i%1000000))%1000000; 
        sum=(sum+tmp)%1000000;        
      
    }
    printf("%d\n",sum);
    return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <math.h>
char a[10000000+5];
int main()
{
    int sum=0,i,j,n,m;
    scanf("%d",&n);
    a[1]=1;
    m=sqrt(n+1);
    for(i=2;i<=m;i++)
       for(j=i*i;j<=n;j=j+i)
          a[j]=1;
    for(i=1;i<=n;i++)
         sum=sum+a[i];
    sum=n-sum;
    printf("%d\n",sum);
    return 0;
}

在这里插入图片描述

#include <stdio.h>
//假设输入的数字没有小于-10000000,本题应该严格给出具体数值,但没有,所以随便设的。 
#define nMax 10000000 
int main()
{
   int n,a,max,med,min;
   max=med=min=-nMax;
   scanf("%d",&n);
   if(n<3)
   {
   	  printf("Invalid Input\n");
   	  return 0;
   }
   for(int i=1;i<=n;i++)
   {
   	  scanf("%d",&a);
	  if(a!=max&&a!=med&&a!=min&&a>max)
	  {
  		 min=med; med=max; max=a;
  		 continue;
  	  }
  	  if(a!=max&&a!=med&&a!=min&&a>med)
	  {
  		 min=med; med=a;
  		 continue;
  	  }
  	  if(a!=max&&a!=med&&a!=min&&a>min)
	  {
  		 min=a;
  		 continue;
  	  }
   } 
   if(min==med&&min==-nMax)
   {
      printf("There is no second largest and third largest element\n");
      return 0;
   }
   if(min!=med&&min==-nMax)
   {
   	  printf("There is no third largest element\n");
   	  return 0;
   }
   printf("%d %d %d\n",max,med,min);
   return 0;
} 

DS 2、循环、函数与递归

在这里插入图片描述

#include <stdio.h>
#include <string.h>
char a[6];
int b[6];
char c[82]; 
int main()
{   
    int al,cl,i,j;
	while(gets(a)&&a[0]!='#')
	{
		gets(c);
		al=strlen(a);
		cl=strlen(c);
		memset(b,0,sizeof(b));
		for(i=0;i<cl;i++)
		{
			for(j=0;j<al;j++)
			  if(c[i]==a[j])
			     b[j]++;
		}
		for(j=0;j<al;j++)
		    printf("%c %d\n",a[j],b[j]);
	} 
}
 

在这里插入图片描述

#include<stdio.h>
int A[10];
// 输出1~n的全排列
void print_permutation(int n, int* A, int cur) 
{
   int i, j;
   if(cur == n) 
          { // 递归边界
             for(i = 0; i < n; i++) printf("%d", A[i]);
             printf("\n");
           }
    else for(i = 1; i <= n; i++) 
           { // 尝试在A[cur]中填各种整数i   2  3  1  cur=1
              int ok = 1;
              for(j = 0; j < cur; j++)
                       if(A[j] == i) { ok = 0;break;} 
                        // 如果i已经在A[0]~A[cur-1]出现过,则不能再选
              if(ok)
                    { A[cur] = i;
                      print_permutation(n, A, cur+1); // 递归调用
                    }
             }
}
int main() 
{  int n;
   scanf("%d",&n);
   print_permutation(n, A, 0); 
   return 0;
}

DS 3、堆栈与队列

在这里插入图片描述

#include <cstdio.h>
#include <cstring>
#include <cstdlib>
#include <stack> 
#include <iostream>
using namespace std;
 
stack <double> q;
int main()
{ 
    string a[31];// 
    bool error=0;//error为0表示“无错误”,1表示“错误” 
    int n=0;
 
    while(cin>>a[n++]) //把所有符号和数字都当做字符串输入 
	   ; 
    n-=1;///n用来统计字符串个数,需要减一
 
    for(int i=n-1;i>=0;i--)
    {    ///如果是符号
        if(a[i].length() == 1 && 
			(a[i][0]== '+'||a[i][0]=='-'||a[i][0]=='*'||a[i][0]=='/'))
	    {
            if(q.size()<2) {error = 1; break;}//如果运算符两边的数据小于2个 
            double aa = q.top(); q.pop();
            double bb = q.top(); q.pop();
            if(a[i][0]== '+') q.push(aa+bb);
            else if(a[i][0]== '-') q.push(aa-bb);
            else if(a[i][0]== '*') q.push((aa*bb));
            else if(a[i][0]== '/') 
			       { if(bb==0){error = 1; break;}//分母为0 
                     q.push(aa/bb);
                   }
        }
        else
	   {    
	        double x = atof(a[i].c_str());
	        //atof函数的头文件是stdlib,可以将char数组转化为double类型变量 
            //.c_str()方法,可以将string类型变量转化为char数组 
			q.push(x);
        }
    }
 
    if(q.size() != 1) error = 1;
    if(error) printf("ERROR");
    else printf("%.1lf",q.top());
    return 0;
}

在这里插入图片描述

#include<stdio.h>
int pos=-1;
int top=-1;
char topp(char *str)
{
	return str[top];
}
void pop()
{
	top--;
}
void push(char *stack,char am)
{
	stack[++top]=am;
}
int main()
{
	char str[250];
	char stack[250];
	char save[250];
	while(gets(str))
	{
		if(str[0]=='.'&&!str[1])break;
		for(int i=0; str[i]; i++)
		{
			if(str[i]=='('||str[i]=='['||str[i]=='{'||str[i]==')'||str[i]=='}'
			        ||str[i]==']') save[++pos]=str[i];
			else if(str[i]=='/'&&str[i+1]=='*')
			{
				save[++pos]='a';//  将/*替换为a
				i++;
			}
			else if(str[i]=='*'&&str[i+1]=='/')
			{
				save[++pos]='b';
				i++;
			}
		}
	}//以上是保存括号
	int flag=0;
	char tep;
	for(int i=0; i<=pos; i++)
	{
		if(save[i]=='('||save[i]=='{'||save[i]=='[')
		{
			push(stack,save[i]);
		}
		else if(save[i]=='a')
		{
			push(stack,save[i]);
		}
		else if(save[i]==')')
		{
			if(top!=-1&&topp(stack)=='(') pop();//top!=-1作用,判断栈是否为空,否则数组越界
			else
			{
				tep=save[i];
				flag=1;
				break;
			}
		}
		else if(save[i]=='}')
		{
			if(top!=-1&&topp(stack)=='{') pop();
			else
			{
				tep=save[i];
				flag=1;
				break;
			}
		}
		else if(save[i]==']')
		{
			if(top!=-1&&topp(stack)=='[') pop();
			else
			{
				tep=save[i];
				flag=1;
				break;
			}
		}
		else if(save[i]=='b')
		{
			if(top!=-1&&topp(stack)=='a')
			{
				pop();
//				printf("出栈操作后,top=%d",top);
			}
			else
			{
				tep=save[i];
				flag=1;
				break;
			}
		}
	}
	if(!flag&&top==-1) printf("YES\n");
	else
	{
		printf("NO\n");
		if(top!=-1)
		{
			if(topp(stack)=='[') printf("[-?\n");
			else if(topp(stack)=='(') printf("(-?\n");
			else if(topp(stack)=='{') printf("{-?\n");
			else if(topp(stack)=='a') printf("/*-?\n");
		}
		else
		{
			if(tep==']') printf("?-]");
			else if(tep==')') printf("?-)");
			else if(tep=='b') printf("?-*/");
			else if(tep=='}') printf("?-}");
			putchar('\n');
		}
	}
	return 0;
}

DS 4、树的应用

在这里插入图片描述

#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 220;
int BST[maxn];
int n,m;
typedef struct TNode
{
    int data;
    struct TNode *left,*right;
}TNode,*BiTree;
void buildtree(BiTree &T,int x)//建树
{
    if(T==NULL)
    {
        T=(BiTree)malloc(sizeof(BiTree));
        T->data=x;
        T->left=NULL;
        T->right=NULL;
    }
    else if(x<T->data)
    {
        buildtree(T->left,x) ;
    }
    else if(x>T->data)
    {
        buildtree(T->right,x);
    }
}
bool Search_BST(BiTree &T,int x)
{
    if(T==NULL||T->data==x) return true;
    if(T->data>x) return Search_BST(T->left,x);
    else return Search_BST(T->right,x);
}
int Get_value(BiTree &T)
{
    if(T==NULL) return -1;
    return T->data;
}
bool Judge_Parent(BiTree T,int x,int y)
{
    if(T==NULL)
    {
        return false;
    }
    if(T->data==x)
    {
        if(Get_value(T->left)==y||Get_value(T->right)==y)
            return true;
    }
    return (Judge_Parent(T->left,x,y)||Judge_Parent(T->right,x,y));
}
bool  Judge_LChild(BiTree T,int x,int y)
{
    if(T==NULL)
    {
        return false;
    }
    if(T->data==y)
    {
        if(Get_value(T->left)==x)
            return true;
    }
    return (Judge_LChild(T->left,x,y)||Judge_LChild(T->right,x,y));
}
bool Judge_RChild(BiTree T,int x,int y)
{
    if(T==NULL)
    {
        return false;
    }
    if(T->data==y)
    {
        if(Get_value(T->right)==x)
            return true;
    }
    return (Judge_RChild(T->left,x,y)||Judge_RChild(T->right,x,y));
}
void Height(BiTree& T,int e,int h,int &c)
{
    if(T==NULL) return;
    if(T->data==e) c=h;
    Height(T->left,e,h+1,c);
    Height(T->right,e,h+1,c);
}
bool Judge_Same(BiTree T,int x,int y)
{
    int f1 , f2;
    Height(T,x,0,f1);
    Height(T,y,0,f2);
    if(f1==f2) return true;
    return false;
}
bool Judge_Bother(BiTree T,int x,int y)
{
    if(T==NULL) return false;
    if(T->left!=NULL&&T->right!=NULL)
    {
        if(T->left->data==x&&T->right->data==y) return true;
        if(T->left->data==x&&T->right->data==y) return true;
    }
    Judge_Bother(T->left,x,y);
    Judge_Bother(T->right,x,y);
}
int main()
{
    scanf("%d",&n);
    BiTree T=NULL;
    for(int i=0;i<n;i++) scanf("%d",&BST[i]);
    for(int i=0;i<n;i++) buildtree(T,BST[i]);
    scanf("%d",&m);
    int _a,_b,_c;
    string a,b,c;
    while(m--)
    {
        scanf("%d",&_a);
        cin>>a;
        if(a=="is")
        {
            cin>>a>>b;
            if(b=="parent")
            {
                cin>>c>>_b;
                if(Judge_Parent(T,_a,_b))
                    printf("Yes\n");
                else
                printf("No\n");
                continue;
            }
            else if(b=="left")
            {
                cin>>b>>c;
                cin>>_b;
                if(Judge_LChild(T,_a,_b))
                 printf("Yes\n");
                else
                printf("No\n");
                continue;
            }
            else if(b=="right")
            {
                cin>>b>>c;
                cin>>_b;
                if(Judge_RChild(T,_a,_b))
                     printf("Yes\n");
                else
                printf("No\n");
                continue;
            }
            else if(b=="root")
            {
                if(T!=NULL&&T->data==_a)
                    printf("Yes\n");
                else
                    printf("No\n");
                continue;
            }
        }
        else if(a=="and")
        {
            cin>>_b;
            cin>>b>>c;
            if(c=="siblings")
            {
                if(Judge_Bother(T,_a,_b))
                     printf("Yes\n");
                else
                printf("No\n");
                continue;
            }
            else
            {
                getline(cin,b);
                if(Judge_Same(T,_a,_b)) // 层数相同
                 printf("Yes\n");
                else
                printf("No\n");
                continue;
            }
        }
    }
}

在这里插入图片描述

# include <iostream>
# include <cmath>
# include <cstring>
# include <string>
# include <map>
# include <algorithm>
# include <vector>
# include <cstdio>
# include <string>
# include <queue>
 
using namespace std;
const int maxn = 10000;
 
 
void insert(int h[], int last)
{
    int father = last / 2;
    while( father && h[father] > h[last])
    {
        swap(h[father], h[last]);
        last = father;
        father = last / 2;
    }
}
 
bool find(int h[], int x, int a, int b, int len)
{
    int root = x;
    queue<int> q;
    q.push(root);
    while(!q.empty())
    {
        root = q.front();
        q.pop();
        int ta = h[root * 2];
        int tb = h[root * 2 + 1];
        if(ta == a && tb == b || ta == b && tb == a)
        {
            return true;
        }
        if(root * 2 <= len && root * 2 + 1 <= len)
        {
            q.push(root * 2);
            q.push(root * 2 + 1);
        }
    }
    return false;
}
 
bool find_p(int h[], int x, int a, int b, int len)
{
    int root = x;
    while(h[root] != a && root <= len)
    {
        root++;
    }
    if(h[root*2] == b || h[root * 2 + 1] == b)
    {
        return true;
    }
    return false;
}
 
 
bool judge(int h[], int len, int a, int b, string str)
{
    if(str == "root")
    {
        if(a == h[1])
        {
            return true;
        }
        else
            return false;
    }
    else if(str == "siblings")
    {
        return find(h, 1, a, b, len);
    }
    else if(str == "parent")
    {
        return find_p(h, 1, a, b, len);
    }
    else
    {
         return find_p(h, 1, b, a, len);
    }
}
 
 
 
int main(int argc, char *argv[])
{
    int h[maxn];
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        cin >> h[i];
        insert(h, i);
    }
 
    for(int i = 0; i < m; i++)
    {
        int a , b;
        string str, link;
        cin >> a >> str;
        if(str != "and")
        {
            cin >> str >> link;//root
            if(link != "root")
            {
                cin >> str >> b;//parent child
            }
        }
        else
        {
            cin >> b >> str >> link;//siblings
        }
        bool flag = judge(h, n, a, b, link);
        if(flag)
        {
            cout <<"T" << endl;
        }
        else
        {
            cout << "F" << endl;
        }
    }
 
    return 0;
}


在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
 
typedef int ElementType;
typedef struct AVLNode* Position;
typedef Position AVLTree;
typedef struct AVLNode{
	ElementType Data;
	AVLTree Left;
	AVLTree Right;
};
//计算树高
int GetHeight(AVLTree A){
	int HL,HR,MaxH;
	if(A==NULL)
		return 0;
	else{
		HL=GetHeight(A->Left);
		HR=GetHeight(A->Right);
		MaxH=max(HL,HR);
		return (MaxH+1); 
	}
}
//左单旋(顺时针)
AVLTree SingleLeftRotation(AVLTree A){
	AVLTree B=A->Left;
	A->Left=B->Right;
	B->Right=A;
	return B;
}
//右单旋(逆时针)
AVLTree SingleRightRotation(AVLTree A){
	AVLTree B=A->Right;
	A->Right=B->Left;
	B->Left=A;
	return B;
}
//左-右双旋
AVLTree DoubleLeftRightRotation(AVLTree A){
	A->Left=SingleRightRotation(A->Left);
	return SingleLeftRotation(A);
}
//右-左双旋
AVLTree DoubleRightLeftRotation(AVLTree A){
	A->Right=SingleLeftRotation(A->Right);
	return SingleRightRotation(A);
}
 
AVLTree Insert(AVLTree A,ElementType X){
	if(!A){
		A=(AVLTree)malloc(sizeof(struct AVLNode));
		A->Data=X;
		A->Left=A->Right=NULL;
	}
	else if(X<A->Data){
		A->Left=Insert(A->Left,X);
		if(GetHeight(A->Left)-GetHeight(A->Right)==2)
			if(X<A->Left->Data)
				A=SingleLeftRotation(A);
			else
				A=DoubleLeftRightRotation(A); 
	}
	else if(X>A->Data){
		A->Right=Insert(A->Right,X);
		if(GetHeight(A->Left)-GetHeight(A->Right)==-2)
			if(X>A->Right->Data)
				A=SingleRightRotation(A);
			else
				A=DoubleRightLeftRotation(A);
	}
	return A;
} 
 
/*验证:输出函数见树的递归输出博客*/ 
 
 
int main(){
	AVLTree A=NULL;
	int n,t;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>t;
		A=Insert(A,t);
	}
	
	cout<<A->Data<<endl;
	
	return 0;
	
}

在这里插入图片描述

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
//代表小顶堆的优先队列
priority_queue<int ,vector<int>,greater<int> > q;
int main(void){
	int n;
	char s[66];
	int p[66];
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		getchar();
		scanf("%c%d",&s[i],&p[i]);
		q.push(p[i]);
	}
	int ans=0;
	//ans即为哈弗曼树带权路径长度和,也就是所对应的哈夫曼编码的长度
	while(q.size()>1){
		int x=q.top();
		q.pop();
		int y=q.top();
		q.pop();
		q.push(x+y);
		ans+=x+y;
	}
	int m;
	scanf("%d",&m);
	for(int i=0;i<m;i++){
		char ss[66][66];
		int sum=0;
		for(int j=0;j<n;j++){
			getchar();
			char c;
			scanf("%c %s",&c,ss[j]);
			sum+=strlen(ss[j])*p[j];
		}
		if(sum!=ans)printf("No\n");
		else{
			int flag=0;
			for(int j=0;j<n;j++){
				int x=strlen(ss[j]);
				for(int l=0;l<n;l++){
					if(j!=l){
						if(strstr(ss[l],ss[j])==&ss[l][0]){
						//查找字符串,如果找到了并且是前缀,就标记为No了
							flag=1;
							break;
						}
					}
				}
				if(flag==1)break;
			}
			if(flag==1)printf("No\n");
			else printf("Yes\n");
		}
	}
	return 0;
}

在这里插入图片描述

#include<iostream>
#include<memory.h>
using namespace std;
const int max_n=1e5;

int root[max_n];

int findRoot(int x){
	if(root[x]==-1) return x;
	else{
		int tmp=findRoot(root[x]);
		root[x]=tmp;
		return tmp;
	}
}

int main(){
	int n;
	cin >> n;
	memset(root,-1,sizeof(root));
	int size=0;
	for(int i=0;i<n;i++){
		int k;
		cin >> k;
		int last=0;
		for(int j=0;j<k;j++){
			int x;
			cin >> x;
			if(x>size) size=x;
			if(j==0){
				last=x;
			}else{
				if(findRoot(last)!=findRoot(x)){
					int a=findRoot(last);
					int b=findRoot(x);
					root[a]=b;
				}
			}
		}
	}
	//输出总人数和不相交的部落个数
	int cnt=0;
	for(int i=1;i<=size;i++){
		if(root[i]==-1){
			cnt++;
		}
	}
	cout<<size<<" "<<cnt<<endl;
	
	//查询
	int k;
	cin >> k;
	for(int i=0;i<k;i++){
		int x,y;
		cin >> x>>y;
		if(findRoot(x)!=findRoot(y)){
			cout<<"N"<<endl;
		}else{
			cout<<"Y"<<endl;
		}
	} 
	return 0;
}

DS 5、图的应用

在这里插入图片描述

#include<stdio.h>
typedef struct {
	int data[150];
	int head,rear;
} quene;
int indegree[100];//记录入度
int map[100][100];//记录路径
int early[100];//记录时间
int n,m;
void init(quene &q) {
	q.head=q.rear=-1;
}
void enquene(quene& q,int a) {
	q.data[++q.rear]=a;
}
bool isempty(quene q) {
	return q.head==q.rear;
}
int outquene(quene& q) {
	return q.data[++q.head];
}
void judge() {
	quene q;
	init(q);
	for(int i=0; i<n; i++) {
		if(indegree[i]==0) {
			enquene(q,i);
		}
	}
	for(int i=0; i<n; i++) early[i]=0;
	int  i=0,max=-1;

	while(!isempty(q)) {
		int v=outquene(q);
		i++;
		for(int j=0; j<n; j++) {
			if(indegree[j]>0&&map[v][j]>=0) {
				if(--indegree[j]==0) {
					enquene(q,j);
				}
				if(early[j]<early[v]+map[v][j]) {
					early[j]=early[v]+map[v][j];
					if(early[j]>max) {
						max=early[j];
					}
				}
			}
		}

	}
	if(i!=n) printf("Impossible\n");
	else  printf("%d\n",max);
}

int main() {
	int s,e,l;
	scanf("%d%d",&n,&m);
	for(int i=0; i<n; i++) {
		for(int j=0; j<n; j++) {
			map[i][j]=-1;
		}
	}
	for(int i=0; i<m; i++) {
		scanf("%d%d%d",&s,&e,&l);
		map[s][e]=l;
		indegree[e]++;
	}
	judge();

	return 0;
}

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int father[105];
int maps[110][110];
int n, m , k;
int finds(int x)
{
    if(x!=father[x]) father[x]=finds(father[x]);
    return father[x];
}
void combine(int x,int y,int t)
{
    if(t==1)
    {
        int a=finds(x);
    int b=finds(y);
    if(a==b)
        return;
    if(a<b)
        father[b]=a;
    else
        father[a]=b;
    }
    else
    {
        maps[x][y] = maps[y][x] = -1;
    }
}
void init()
{
    for(int i=0;i<=n;i++)
      father[i]=i;
}
int main()
{
   scanf("%d%d%d",&n,&m,&k);
   init();
   memset(maps,0,sizeof(maps));
   for(int i=1;i<=m;i++)
   {
       int x,y,t;
       scanf("%d%d%d",&x,&y,&t);
       combine(x,y,t);
   }
   int x,y;
   for(int i=0;i<k;i++)
   {
        cin>>x>>y;
        if(finds(x)==finds(y)&&maps[x][y]!=-1)
        {
            printf("No problem\n");
        }
        else if(finds(x)==finds(y)&&maps[x][y]==-1)
        {
            printf("OK but...\n");
        }
        else if(finds(x)!=finds(y)&&maps[x][y]==-1)
        {
            printf("No way\n");
        }
        else
            printf("OK\n");
   }
}

在这里插入图片描述

#include <iostream>
#include <queue>

using namespace std;

//结点定义
typedef struct {
	int num;	//门后面的门的总数
	int *p;		//指向门之后的门的编号所组成的数组
}node;

int input(node *a, int n);
int level(node *a, int r);

int main() {
	node *a;	//存储所有门的信息(整棵树)
	int root;	//root表示第一扇门
	int n;		//一共n扇门,读入n
	cin >> n;	
	a = new node[n + 1];	//分配空间
	root = input(a, n);		//输入每扇门信息,得到第一扇门
	cout << level(a, root);	//从第一扇门a[root]开始遍历,输出最后一个即最深结点
	return 0; 
}

//循环输入n扇门,并返回第一扇门的编号,即数组下标
int input(node *a, int n) {
	int result = 0;		//用于存储第一扇门的编号(下标)并输出
	// 设置数组查找第一扇门,分配空间并初始化
	bool *doors;		
	doors = new bool[n + 1];
	for (int k = 1; k <= n; k++) {
		doors[k] = false;
	}
	//循环输入
	for (int i = 1; i <= n; i++) {
		cin >> a[i].num;
		if (a[i].num != 0) {	//如果不为0,分配空间并循环输入
			a[i].p = new int[a[i].num];	//为p数组分配空间
			for (int j = 0; j < a[i].num; j++) {
				cin >> a[i].p[j];
				doors[a[i].p[j]] = true;
			}
		}
		else {		//如果门后没有路,就将指针置空
			a[i].p = NULL;
		}
	}
	//遍历数组root,为false的门为第一扇门
	for (int m = 1; m <= n; m++) {
		if (doors[m] == false) {
			result = m;
			break;
		}
	}
	return result;
}

//r为第一扇门编号,从a[r]开始进行遍历,返回最后一个,即最深的结点编号
int level(node *a, int r) {
	queue<int> q;
	int temp;	//当前队头,即当前门的编号
	q.push(r);
	//树的层次遍历,当前层一个个遍历,将子结点入队
	while (!q.empty()) {
		temp = q.front();	//得到队头再出队
		q.pop();
		if (a[temp].num != 0) {		//编号temp的门后还有门,就将他们入队
			for (int i = 0; i < a[temp].num; i++) {
				q.push(a[temp].p[i]);
			}
		}
	}
	return temp;	//层次遍历,最后一个值覆盖temp,即为最深结点
}

在这里插入图片描述

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct Bian{
	int v1,v2;
	int w;     ///权值
}bian;
int n,m;
int f[1001];   ///并查集使用的数组
bool cmp(const bian a,const bian b){
	return a.w < b.w;
}
void init(){
	for(int i = 1; i <= 1001; ++i){
		f[i] = i;
	}
}
int getf(int a){     ///并查集里寻找祖先
    if(a == f[a]) return a;
    return f[a] = getf(f[a]);
}
int merge(int a,int b){   ///并查集的合并
    int ta,tb;
    ta = getf(a);
    tb = getf(b);
    if(ta == tb) return 0;
    f[ta] = tb;
    return 1;
}
int main(int argc, char *argv[]) {
	int ans = 0;
	int count = 0;
	vector<bian> v;
	init();
	scanf("%d%d",&n,&m);
	getchar();
	int temp = m;
	while(m--){    ///边的输入,构建图的邻接表
		bian tmp1;
		int x,y,ww;
		scanf("%d%d%d",&x,&y,&ww);
		tmp1.v1 = x;
		tmp1.v2 = y;
		tmp1.w = ww;
		v.push_back(tmp1);
	}
	sort(v.begin(),v.end(),cmp);    ///根据权值对边排序
	for(int i = 0; i < v.size(); ++i){
		int t = merge(v[i].v1,v[i].v2);
		if( t ){
			ans += v[i].w;
			count++;
		}
		if(count == n-1) break;
	}
	if(count != n-1) printf("-1\n");   ///如果最后没有选出n-1条边,那么只能是条件不够
	else 
	    printf("%d\n",ans);
	return 0;
}

在这里插入图片描述

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;

const int INF = 1e5;
const int MAX = 109;

int N, M;
int dis[MAX][MAX];

void floyd() // 获取每两个顶点间的最短路径
{
    for( int k = 1; k <= N; k++ )
    {
        for( int i = 1; i <= N; i++ )
        {
            for( int j = 1; j <= N; j++ )
            {
                if( i != j && dis[i][k] + dis[k][j] < dis[i][j] )
                    dis[i][j] = dis[i][k] + dis[k][j];
            }
        }
    }
}
int main()
{
    scanf("%d%d", &N, &M);
    // 初始化
    for( int i = 1; i <= N; i++ )
    {
        for( int j = 1; j <= N; j++ )
        {
            dis[i][j] = INF;
        }
    }

    int u, v, cost;
    for( int i = 0; i < M; i++ )
    {
        scanf("%d%d%d", &u, &v, &cost);
        dis[u][v] = dis[v][u] = cost;
    }

    floyd();

    int maxx = 0, minn = INF, ans = 0;

    for( int i = 1; i <= N; i++ )
    {
        maxx = 0;
        for( int j = 1; j <= N; j++ )
        {
//            printf("%d ", dis[i][j]);
            if( i != j && maxx < dis[i][j] )
            {
                maxx = dis[i][j];
            }
        }
//        printf("\n");
        if( maxx == INF )
        {
            printf("0\n");
            return 0;
        }
        if( minn > maxx )
        {
            minn = maxx;
            ans = i;
        }
    }
    printf("%d %d\n", ans, minn);
    return 0;
}

DS 6、内部排序

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;

ElementType *ReadInput(int N);
void solve(ElementType A[], ElementType ansArr[], int N);
void PrintArr(ElementType A[], int N);

void PercDown(ElementType A[], int p, int N);

int Check_Insertion_Sort(ElementType A[], ElementType ansArr[], int N);
void Heap_Sort(ElementType A[], int N);

int main()
{
    int N;
    ElementType *arr, *ansArr;
    scanf("%d", &N);
    arr = ReadInput(N);
    ansArr = ReadInput(N);
    solve(arr, ansArr, N);
    free(arr);
    free(ansArr);

    return 0;
}

ElementType *ReadInput(int N)
{
    ElementType *arr;
    int i;
    arr = (ElementType *)malloc(sizeof(ElementType) * N);
    for (i = 0 ; i < N; ++i)
        scanf("%d", &arr[i]);
    return arr;
}

void PrintArr(ElementType A[], int N)
{
    int i;
    for ( i = 0; i < N - 1; ++i)
        printf("%d ", A[i]);
    printf("%d", A[i]);
}

void solve(ElementType A[], ElementType ansArr[], int N)
{
    if (Check_Insertion_Sort(A, ansArr, N)) {   // 判断是否为插入排序
        printf("Insertion Sort\n");
        PrintArr(ansArr, N);
    }
    else {  // 此时一定是堆排序
        Heap_Sort(ansArr, N);
        printf("Heap Sort\n");
        PrintArr(ansArr, N);
    }
}

void PercDown(ElementType A[], int p, int N)
{
    int Parent, Child;
    ElementType X;

    X = A[p];
    for (Parent = p; (Parent * 2 + 1) < N; Parent = Child) {
        Child = Parent * 2 + 1;
        if ((Child != N - 1) && (A[Child] < A[Child + 1]))
            ++Child;
        if (X >= A[Child]) break;
        else
            A[Parent] = A[Child];
    }
    A[Parent] = X;
}

int Check_Insertion_Sort(ElementType A[], ElementType ansArr[], int N)
{
    int i, pos, flag;
    ElementType tmp;

    flag = 1;
    for (i = 0; i < N - 1; ++i) {   // 找到第一个非有序位置
        if (ansArr[i] > ansArr[i + 1]) {
            pos = i + 1;
            break;
        }
    }
    for (i = pos; i < N; ++i) {     // 判断非有序部分是否和输入数据对应位置一样
        if (A[i] != ansArr[i]) {
            flag = 0;
            break;
        }
    }
    if (flag) { // 如果是插入排序,进行下一次插入排序操作
        tmp = ansArr[pos];
        for (; pos > 0 && tmp < ansArr[pos - 1]; --pos)
            ansArr[pos] = ansArr[pos - 1];
        ansArr[pos] = tmp;
    }
    return flag;
}

/*堆排序的逻辑:
  将堆顶元素(也即是堆里的最大的元素)取出,放到数组下标为i的位置
  而下边i的元素放到堆顶(下标为0的位置)
  然后将前i个元素再调整成最大堆
  这道题就是将部分堆排序的ansArr再进行一次上述步骤
*/
void Heap_Sort(ElementType A[], int N)
{
    ElementType Tmp;
    int i;

    for (i = N - 1; i > 0 && A[i] >= A[0] ; --i) ;
    if (i != 0) {
        Tmp = A[0];
        A[0] = A[i];
        A[i] = Tmp;
        PercDown(A, 0, i);
    }
}

在这里插入图片描述

java

import java.util.Scanner;
 
public class Main {
 
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		int k = cin.nextInt();
		String[] strs = new String[100];
		String temp;
		for (int i = 0; i < n; i++) {
			strs[i] = cin.next();
		}
		for (int j = 0; j < k; j++) {
			for (int i = 0; i < n - 1 - j; i++) {
				if (strs[i].compareTo(strs[i + 1]) > 0) {
					temp = strs[i];
					strs[i] = strs[i + 1];
					strs[i + 1] = temp;
				}
			}
		}
		for (int i = 0; i < n; i++) {
			System.out.println(strs[i]);
		}
	}
}


在这里插入图片描述

#include<cstdio>
#include<algorithm>
#include<vector>
#include<iostream>//记得加上
using namespace std;
vector<int> va,vb;
int main(){
	int n,x;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&x);
		va.push_back(x);
	}
	for(int i=0;i<n;i++){
		scanf("%d",&x);
		vb.push_back(x);
	}
	int t=n;
	make_heap(va.begin(),va.begin()+t,less<int>());
	while(va!=vb&&t>0){
		pop_heap(va.begin(),va.begin()+t,less<int>());
		t--;
	}
	if(va==vb){
		printf("Heap Sort\n");
		pop_heap(va.begin(),va.begin()+t,less<int>());
		vb=va;
	}
	else{
		t=1;
		while(t<n&&vb[t-1]<=vb[t]) t++;
		while(t>0&&vb[t-1]>vb[t]){
			swap(vb[t-1],vb[t]);
			t--;
		}
		printf("Insertion Sort\n");
	}
	for(int i=0;i<n;i++){
		printf("%d%c",vb[i]," \n"[i==n-1]);
	}
	return 0;
}

在这里插入图片描述

#include<bits/stdc++.h>
 
using namespace std;
const int maxn = 41700;
struct ss
{
    char num[17];
    int s;
    int rank;//总排名
    int mark;
    int flag;
} stu[maxn];
bool cmp1(ss a, ss b)//排序辅助函数,有困难可搜索cmp函数详解
{
    if(a.s == b.s)
    {
        return strcmp(a.num, b.num) < 0;
    }
    return a.s > b.s;
}
int main()
{
    int N;
    int k[117];
    int sum = 0;
    scanf("%d",&N);
    {
        int i, j;
        int l = 0, p = 0;
        for(i = 1; i <= N; i++)
        {
            scanf("%d",&k[i]);
            sum += k[i];
            int tt = l;
            for(j = 1; j <= k[i]; j++)
            {
                scanf("%s%d",stu[l].num,&stu[l].s);
                stu[l].mark = i;
                l++;
            }
            sort(stu+tt,stu+l,cmp1);
            p = 2;
            stu[tt].rank = 1;
            for(int h = tt+1; h < l; h++)
            {
                if(stu[h-1].s == stu[h].s)
                {
                    stu[h].rank = stu[h-1].rank;
                }
                else
                {
                    stu[h].rank = p;
                }
                p++;
            }
        }
        sort(stu,stu+l,cmp1);
        int f = 1;
        int flag = 0;
        printf("%d\n",sum);
        stu[0].flag = 1;
        printf("%s %d %d %d\n",stu[0].num,stu[0].flag,stu[0].mark,stu[0].rank);//输出第一名
        p = 2;
        for(int h = 1; h < l; h++)
        {
            if(stu[h-1].s == stu[h].s)
            {
                stu[h].flag = stu[h-1].flag;
            }
            else
            {
                stu[h].flag = p;
            }
            p++;
        }
        for(i = 1; i < l; i++)
        {
            printf("%s %d ",stu[i].num,stu[i].flag);
            printf("%d %d\n",stu[i].mark,stu[i].rank);
        }
    }
    return 0;
}

在这里插入图片描述


#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct UserNode {
	int total;
	int perfect;
	int *score;
}; 
UserNode *ranklist[10001];
 
bool cmp(int a, int b) {
	if (ranklist[a]->total > ranklist[b]->total)
		return true;
	else if (ranklist[a]->total == ranklist[b]->total) {
		if (ranklist[a]->perfect > ranklist[b]->perfect)
			return true;
		else if (ranklist[a]->perfect == ranklist[b]->perfect)
			if (a < b)return true;
	}
	return false;
}
 
int main() {
	int i, j, t, n, k, m, id, problem, score, flag, r, temp, s[5];
	vector<int> rlist;
	
	scanf("%d%d%d", &n, &k, &m);
	for (i = 0;i < k;i++)
		scanf("%d", &s[i]);
	for (i = 1;i <= n;i++)
		ranklist[i] = NULL;
	while (m--) {
		scanf("%d%d%d", &id, &problem, &score);
		if (!ranklist[id]) {
			ranklist[id] = new UserNode;
			ranklist[id]->score = new int[k];
			for (j = 0;j < k;j++)
				ranklist[id]->score[j] = -2;
			ranklist[id]->total = 0;
			ranklist[id]->perfect = 0;
		}
		if (ranklist[id]->score[problem - 1] < score) 	
			ranklist[id]->score[problem - 1] = score;
	}
	for (i = 1;i <= n;i++) {
		if (ranklist[i]) {
			flag = 0;
			for (j = 0;j < k;j++) {
				if (ranklist[i]->score[j] >= 0) {
					flag = 1;
					ranklist[i]->total += ranklist[i]->score[j];
				}	
				if (ranklist[i]->score[j] == s[j])
					ranklist[i]->perfect++;
			}
			if (flag) rlist.push_back(i);	
		}
	}
 
	sort(rlist.begin(), rlist.end(), cmp);
	temp = 1;
	for (i = 0;i < k;i++)
		temp += s[i];
	for (i = 0;i < rlist.size();i++) {
		t = rlist[i];
		if (ranklist[t]->total < temp) {
			r = i + 1;
			temp = ranklist[t]->total;
		}
		printf("%d %05d %d", r, t, ranklist[t]->total);
		for (j = 0;j < k;j++) {
			if (ranklist[t]->score[j] == -2)
				printf(" -");
			else if(ranklist[t]->score[j] == -1)
				printf(" 0");
			else
				printf(" %d", ranklist[t]->score[j]);
		}
		printf("\n");
		
	}
	return 0;
}

在这里插入图片描述


#include <iostream>
#include <algorithm>
#define maxage 51
using namespace std;
int main()
{
	int n,age;
	cin >> n;
	int count[maxage] = { 0 };
	for (int i = 0; i < n; i++)
	{
		cin >> age;
		count[age]++;
	}
	for (int i = 0; i < maxage; i++)
		if (count[i])
			cout << i << ":" << count[i] << endl;
	return 0;
}

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
const int M = 1e7 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
int a[N],n;
map<int,int> m;
int main()
{
    int p0;
    cin >> n;
    for(int i = 0;i < n;i ++){
        cin >> a[i];
        if(a[i] == 0){
           p0 = i;
        }
        m[a[i]] = i;
    }
    int cnt = 0;
    int q = 0;
    while(1){
        if(a[p0] != p0){
            int p1 = m[p0];
            //1
            m[a[p0]] = p1;
            m[a[p1]] = p0;
            //2
            swap(a[p0],a[p1]);
            p0 = p1;
            cnt ++;
        }else{
            bool flag = false;
            int p1;
            for(;q < n;q ++){
                if(a[q] != q){
                    p1 = q;
                    flag = true;
                    break;
                }
            }
            if(!flag) break;
            else{
                cnt ++;
                p0 = p1;
                m[a[p1]] = p0;
                m[a[p0]] = p1;
                //2
                swap(a[p0],a[p1]);
                p0 = p1;
                cnt ++;
            }
        }
    }
    cout << cnt;
    return 0;
}

在这里插入图片描述

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct mooncake{
    float mount, price, unit;
};
int cmp(mooncake a, mooncake b) {
    return a.unit > b.unit;
}
int main() {
    int n, need;
    cin >> n >> need;
    vector<mooncake> a(n);
    for (int i = 0; i < n; i++) scanf("%f", &a[i].mount);
    for (int i = 0; i < n; i++) scanf("%f", &a[i].price);
    for (int i = 0; i < n; i++) a[i].unit = a[i].price / a[i].mount;
    sort(a.begin(), a.end(), cmp);
    float result = 0.0;
    for (int i = 0; i < n; i++) {
        if (a[i].mount <= need) {
            result = result + a[i].price;
        } else {
            result = result + a[i].unit * need;
            break;
        }
        need = need - a[i].mount;
    }
    printf("%.2f",result);
    return 0;
}

在这里插入图片描述

#include"stdio.h"
#include"stdlib.h"
#include"string.h"
 
int temp[10000],num_place[100000],num[100000];
int nbit,n;

int count_bit()
{
    int max=0,count=0,temp;
    for(int i=0;i<n;i++)
    {
        count=1;
        temp=num[i];
        while(temp>0)
        {
            temp=temp/10;
            count++;
        }
        if(max<count)
            max=count;
    }
    return max-1;
}
 
void RadixSort()
{
    int radix=1,t;
     nbit=count_bit();
  memset(temp,0,sizeof(temp));
 
     for(int i=1;i<=nbit;i++)
     {
         //先将数组初始化,等下将要记录有多少个位数是相同的数字的个数
         for(int j=0;j<10;j++)
           num_place[j]=0;
 
        //用来保存从低位开始的数值位,记录个数
        for(int j=0;j<n;j++)
        {
            t=(num[j]/radix)%10;
            ++num_place[t];
        }
 
        //累加,计算比它小的数字个数有多少个,是为等下的 temp[num_place[t]]=num[j]操作
        for(int j=1;j<10;j++)
          num_place[j]+=num_place[j-1];
 
       //从最后面开始找。
        for(int j=n-1;j>=0;j--)
        {
            t=(num[j]/radix)%10;
            --num_place[t];//替换的位置
            temp[num_place[t]]=num[j];
        }
 
        radix*=10;
        for(int j=0;j<n;j++)
          num[j]=temp[j];
 
        for(int j=0;j<n;j++)
        {
              printf("%d ",temp[j]);
        }
        printf("\n");
     }
    return ;
}
 
int main()
{
     int i;
  while(scanf("%d",&n)==1)
  {
    for(i=0;i<n;i++)
     {
         scanf("%d",&num[i]);
     }
 
     RadixSort();
}
    return 0;
}

DS 7、散列查找

在这里插入图片描述

#include <cstdio>
#include <cstdlib>
#include <string.h>
 
typedef struct node {
    char phone[15];     // 存放电话号码
    int num;            // 统计出现次数
    struct node* next;  // 一下个结点的指针
} Node;
 
typedef struct {
    int TableSize;
    Node* Table;
} HashTable;
 
int nextPrime( int n ) {
    while( 1 ) {
        bool flag = true;
        for( int i = 2; i < n; i++ ) {
            if( n % i == 0 ) {
                flag = false;
                break;
            }
        }
        if( flag ) break;
        n++;
    }
 
    return n;
}
 
HashTable* createHashTable( int n ) {
    HashTable* H = ( HashTable* )malloc( sizeof( HashTable ) );
    H->TableSize = nextPrime( n );
 
    H->Table = ( Node* )malloc( ( H->TableSize ) * sizeof( Node ) );
 
    for( int i = 0; i < H->TableSize; i++ ) {
        H->Table[i].phone[0] = '\0';
        H->Table[i].num = 0;
        H->Table[i].next = NULL;
    }
 
    return H;
}
 
int Hash( HashTable* H, char key[] ) {
    int index = 0;
    for( int i = 6; i <= 10; i++ ) {
        index = index * 10 + key[i] - '0';
    }
 
    return index;
}
 
Node* Find( HashTable* H, char key[] ) {
    int index = Hash( H, key ) % ( H->TableSize );     // 初始散列位置
    //printf( "初始散列位置: %d\n", index );
 
    Node* p;
    p = H->Table[index].next;
 
    while( p && strcmp( p->phone, key ) ) {
        p = p->next;
    }
 
    return p;
}
 
void Insert( HashTable* H, char key[] ) {
    Node* p = Find( H, key );
 
    if( !p ) {
        //printf( "没找到\n" );
        Node* newNode = ( Node* )malloc( sizeof( Node ) );
 
        int index = Hash( H, key ) % ( H->TableSize );
        newNode->next = H->Table[index].next;
        H->Table[index].next = newNode;
 
        strcpy( newNode->phone, key );
        newNode->num = 1;
    }
    else {
        //printf( "找到 %s\n", p->phone );
        p->num++;
    }
}
 
void ScanAndOutput( HashTable* H ) {
    int i, MaxCnt, PCnt;
    char MinPhone[15];
 
    MaxCnt = PCnt = 0;
    MinPhone[0] = '\0';
 
    for( i = 0; i < H->TableSize; i++ ) {
        Node* ptr = H->Table[i].next;
        while( ptr ) {
            if( ptr->num > MaxCnt ) {
                MaxCnt = ptr->num;
                strcpy( MinPhone, ptr->phone );
                PCnt = 1;
            }
            else if( ptr->num == MaxCnt ) {
                PCnt++;
                if( strcmp( MinPhone, ptr->phone ) > 0 ) {
                    strcpy( MinPhone, ptr->phone );
                }
            }
            ptr = ptr->next;
        }
    }
 
    printf( "%s %d", MinPhone, MaxCnt );
    if( PCnt > 1 ) printf( " %d", PCnt );
    printf( "\n" );
}
 
void DestroyTable( HashTable* H ) {
    for( int i = 0; i < H->TableSize; i++ ) {
        Node* ptr = H->Table[i].next;
        while( ptr ) {
            Node* tmp = ptr->next;
            free( ptr );
            ptr = tmp;
        }
    }
    free( H->Table );
    free( H );
}
 
int main() {
    //freopen( "123.txt", "r", stdin );
    int N, i;
    char input[15];
 
    scanf( "%d", &N );
 
    // 创建Hash表
    HashTable* H = createHashTable( 2 * N );
 
    //printf( "%d\n", H->TableSize );
 
    for( int i = 0; i < N; i++ ) {
        scanf( "%s", input ); Insert( H, input );
        scanf( "%s", input ); Insert( H, input );
    }
 
    ScanAndOutput( H );
    DestroyTable( H );
 
    return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
 
int main()
{
	set<int> st[51];
	int n,m,i;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&m);
		while(m--)
		{
			int k;
			scanf("%d",&k);
			st[i].insert(k);
		} 
		
	}
	
	int c;
	scanf("%d",&c);
	while(c--)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		int cnt=0;
		for(set<int>::iterator it=st[a].begin();it!=st[a].end();it++)
		{
			if(st[b].count(*it))
			cnt++;
		}
		int sum=st[a].size()+st[b].size()-cnt;
		printf("%.2lf%%\n",cnt*100.0/sum);
	}
	return 0;
}

在这里插入图片描述

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
typedef pair<int,int> P;
const int maxn = 1000 + 2;
int n,a[maxn],vis[maxn],viss[maxn];
vector<int> b;
int main()
{
    int fir = 0;
    scanf("%d",&n);
    memset(vis,0,sizeof(vis));
    memset(viss,0,sizeof(viss));
    for(int i = 0;i < n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i] == -1) continue;
        b.push_back(a[i]);
    }
    sort(b.begin(),b.end());
//    for(int i = 0;i < (int)b.size();i++)
//    {
//        if(i) printf(" ");
//        printf("%d",b[i]);
//    }
//    printf("\n");
    while(true)
    {
        int i;
        for(i = 0;i < (int)b.size();i++)
        {
            if(vis[i]) continue;
//            printf("%d %d\n",b[i],a[b[i] % n]);
            if(a[b[i] % n] == b[i])
            {
                if(fir) printf(" ");
                else fir = 1;
                printf("%d",b[i]);
                vis[i] = viss[b[i] % n] = 1;
                break;
            }
            else
            {
                bool ok = false;
                for(int j = 0;j < n;j++)
                {
                    int x = ((b[i] % n) + j) % n;
                    if(!viss[x] && a[x] != b[i]) break;
                    if(viss[x] && a[x] != b[i]) continue;
                    if(fir) printf(" ");
                    else fir = 1;
                    ok = true;
                    vis[i] = viss[x] = 1;
                    printf("%d",b[i]);
                    break;
                }
                if(ok) break;
            }
        }
        if(i == b.size()) break;
    }
    return 0;
}

在这里插入图片描述

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
#include <climits>
#include <set>
#include <stack>
#include <string>
#include <map>
#include <vector>
using namespace std;
typedef long long ll;
static const int MAX_N = 1e5 + 5;
struct Per {
	bool sex;
	int id;
};
map<string, Per>mps1;
int pre[MAX_N];
string s1, s2, s3, s4;
void init() {
	for (int i = 1; i < MAX_N; ++i)pre[i] = i;
}
int Find(int x) {
	int rt = pre[x];
	if (pre[x] != x) rt = Find(pre[x]);
	return rt;
}
bool judge(int x, int y) {	
	/*
		两人存在公共祖先的情况下
		判断这个共同祖先是否在五代以内
	*/int ret = 1;
	while (x != pre[x] && y != pre[y]) {
		x = pre[x];
		y = pre[y];
		++ret;
		if (ret == 5) return true;	//不在五代以内
		if (x == y) return false;	//五代以内存在共同祖先
	}
	return false;	
/*
	能够跳出while循环
	说明某个人无五代祖先
	但是已经判断出两人存在公共祖先
	说明两人五代以内存在公共祖先,返回false
*/
}
int main() {
	ios::sync_with_stdio(false);
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	init();
	int n;
	cin >> n;
	int cnt = 0;
	vector<vector<string> >in(n);
	for (int i = 0; i < n; ++i) {
		cin >> s1 >> s2;
		mps1[s1].id = ++cnt;
		in[i].push_back(s1);
		in[i].push_back(s2);
	}
	for (int i = 0; i < n; ++i) {
		s1 = in[i][0], s2 = in[i][1];
		if (s2.length() > 4 && s2.substr(s2.length() - 4, 4) == "sson") {
			pre[mps1[s1].id] = mps1[s2.substr(0, s2.length() - 4)].id;
			mps1[s1].sex = true;
		}
		else if (s2.length() > 7 && s2.substr(s2.length() - 7, 7) == "sdottir") {
			pre[mps1[s1].id] = mps1[s2.substr(0, s2.length() - 7)].id;
			mps1[s1].sex = false;
		}
		else {
			if (s2.back() == 'm')	mps1[s1].sex = true;
			else mps1[s1].sex = false;
		}
	}
	int m;
	/*for (map<string, Per>::iterator it = mps1.begin(); it != mps1.end(); ++it) {
		cout << it->first << " " << it->second.id << " " << pre[it->second.id] << endl;
	}*/
	cin >> m;
	while (m--) {
		cin >> s1 >> s2 >> s3 >> s4;
		if (!mps1[s1].id || !mps1[s3].id) printf("NA\n");
		else if (mps1[s1].sex == mps1[s3].sex) printf("Whatever\n");
		else if (Find(mps1[s1].id) != Find(mps1[s3].id)) printf("Yes\n");
		else if (judge(mps1[s1].id, mps1[s3].id)) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

DS 8、综合应用案例分析

在这里插入图片描述

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(){
    int n;
    scanf("%d", &n);
    vector<int> origin(n), target(n);
    for(int i = 0; i < n; ++i){
        scanf("%d", &origin[i]);
    }
    for(int i = 0; i < n; ++i){
        scanf("%d", &target[i]);
    }
    //插入排序的特征是,前面为有序的,后面与原始序列一样。
    //如果不是插入排序,则是归并排序
    int index = -1;
    for(int i = 1; i < n; ++i){
        if(target[i] < target[i - 1]){
            index = i;
            break;
        }
    }
    int flag = 0; //0为插入排序,1为归并排序
    for(int i = index; i < n; ++i){
        if(target[i] != origin[i]){
            flag = 1;
            break;
        }
    }
    if(flag == 0){
        printf("Insertion Sort\n");
        //输出下一步
        sort(target.begin(), target.begin() + index + 1);
        printf("%d", target[0]);
        for(int i = 1; i < n; ++i){
            printf(" %d", target[i]);
        }
    }
    else if(flag == 1){
        printf("Merge Sort\n");
        //输出下一步
        int k = 1;
        bool isNotEqual = true;
        while(isNotEqual){
            isNotEqual = false;
            if(!equal(origin.begin(), origin.end(), target.begin())){ //如果不同的话,就进行一次归并排序
                isNotEqual = true;
            }
            k *= 2;
            for(int i = 0; i < n / k; ++i){
                sort(origin.begin() + i * k, origin.begin() + (i + 1) * k);
            }
            //将剩下的排序
            sort(origin.begin() + k * (n / k), origin.end());
        }
        printf("%d", origin[0]);
        for(int i = 1; i < n; ++i){
            printf(" %d", origin[i]);
        }
    }
    printf("\n");
    return 0;
}

在这里插入图片描述

#include<cstdio>
#include<cstring>
#include<cstdlib>
const int maxn = 1000100;

int KMP(char *string, char *pattern);
void buildMatch(char *pattern, int *match);

int main()
{
    char string[maxn] = {0};
    char pattern[maxn] = {0};
    int n;
    
    scanf("%s", &string);
    scanf("%d", &n);
    
    for (int i = 0; i < n; i++)
    {
        scanf("%s", &pattern);
        int p = KMP(string, pattern);
        if (p != -1)
        {
            printf("%s", string+p);
        }
        else
        {
            printf("Not Found");
        }
        
        if (i < n-1)
        {
            printf("\n");
        }
    }
    
    return 0;
}

int KMP(char *string, char *pattern)
{
    int n = strlen(string);
    int m = strlen(pattern);
    
    if (n < m)
    {
        return -1;
    }
    int *match = (int *)malloc(sizeof(int) * m);
    
    buildMatch(pattern, match);
    
    int s = 0;
    int p = 0;
    while (s < n && p < m)
    {
        if (string[s] == pattern[p])
        {
            s++;
            p++;
        }
        else if(p > 0)
        {
            p = match[p-1] + 1;
        }
        else
        {
            s++;
        }
    }
    
    return (p == m) ? (s - m) : -1;
}

void buildMatch(char *pattern, int *match)
{
    int m = strlen(pattern);
    match[0] = -1;
    
    for (int j = 1; j < m; j++)
    {
        int i = match[j-1];
        while( (i >= 0) && (pattern[i + 1] != pattern[j]) )
        {
            i = match[i];
        }
        
        if (pattern[i + 1] == pattern[j])
        {
            match[j] = i + 1;
        }
        else
        {
            match[j] = -1;
        }
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值