PAT 浙大版《数据结构(第2版)》题目集 编程题 实例1.1~习题8.5

用C还是C++自己注意一下

实例1.1 最大子列和问题 (20分)

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    int n,d,sum=0,ans=0;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>d;
        sum+=d;
        if(sum<0)
            sum=0;
        if(sum>ans)
            ans=sum;
    }
    cout<<ans;
    return 0;
}

习题2.1 简单计算器 (20分)

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

int main() {
	int result, a1, a2;
	char b;
	scanf("%d", &a1);
	result = a1;
	while (1) {
		scanf("%c", &b);
		if (b == '=') {
			printf("%d", result);
			break;
		}
		scanf("%d", &a2);
		if (b == '+') result = result + a2;
		else if (b == '-') result = result - a2;
		else if (b == '*') result = result * a2;
		else if (b == '/') {
			if (a2 == 0) {
				printf("ERROR");
				break;
			}
			else {
				result = result / a2;
			}
		}
		else {
			printf("ERROR");
			break;
		}
	}
	return 0;
}

习题2.2 数组循环左移 (20分)

#include<stdio.h>

void turn(int *p , int i , int n );

int main()
{
	
	int n,m;
	scanf("%d %d",&n,&m);
	if(m>=n)
	m=m%n;
	
	int i,a[n];
	for(i=0;i<n;i++)
	{   if(i!=n-1)
		scanf("%d ",&a[i]);
		else
		scanf("%d",&a[i]);
	}	

	turn(a,0,m);
	turn(a,m,n+m);
	turn(a,0,n);	
	
	for(i=0;i<n;i++)
	{   if(!i)
		printf("%d",a[i]);
		else
		printf(" %d",a[i]);
	}
	
	return 0;
}

	void turn(int *p , int i , int n )
{
   int t;
   
   for(;i<n/2;i++)
	{
		t=*(p+i);
		*(p+i)=*(p+n-i-1);
		*(p+n-i-1)=t;	
	}

}

习题2.3 数列求和-加强版 (20分)

#include<stdio.h>
#define maxzie 100000
int sum( int a, int n , int *p);
int main()
{
	int A,N,s[maxzie+1],count;
	scanf("%d %d",&A,&N);
	if(N!=0)	//N=0的情况 
	{
		count=sum(A,N,s);
	
		for(count--;count>=0;count--) //低位在数组末尾 
    	printf("%d",s[count]);		
	}
	else printf("0");
}
int  sum( int a, int n , int *p)
{
	int i,m,remain=0,count=0;
	for(i=0;i<n;i++)
	{	
		m=a*(n-i)+remain;
		p[i]=m%10;
	 	remain=m/10;
	 	count++;   //count为数的位数
	}
	if(remain!=0) 
	{
		p[i]=remain;
		count++;	
	}
	return count;
}

习题2.8 输出全排列 (20分)

#include <stdio.h>
#include<string.h>

int Mark[10];
int Element[10];
void dfs(int n,int pcur){
    if(pcur==n){//递归出口
          int i;
        for(i=0;i<n;i++){
            printf("%d",Element[i]);
        }
        printf("\n");
        return;
    }
    else{
            int j;
        for(j=1;j<=n;j++){
            //判断j是否被使用过;如若使用过,将不再放入Element[ ]数组中
            if(!Mark[j]){
                //放值
                Element[pcur]=j;
               //标记j已被使用
                Mark[j]=1;
                //递归,实现深搜
                dfs(n,pcur+1);
                //回溯部分,设置当前值并未被使用
                Mark[j]=0;
            }
        }
    }
}

int main(){
    int n;
    scanf("%d",&n);
    memset(Mark,0,sizeof(Mark));
    dfs(n,0);
    return 0;
}

习题3.4 最长连续递增子序列 (20分)

#include <stdio.h>
#define MAXSIZE 100000
typedef struct Node{
    int Data[MAXSIZE];
    int size;
}Node, *List; /*传递结构指针效率高*/
List Read(List L);
void PrintSeq(List L);

int main(void){
    Node node;
    List L = &node;
    L = Read(L);
    PrintSeq(L);

    return 0;
}

List Read(List L){
    int n, i;
    scanf("%d", &n);
    L->size = n;
    for(i=0; i<n; i++){
        scanf("%d", &L->Data[i]);
    }

    return L;
}

void PrintSeq(List L){
    int maxL, maxR, maxLen, l, r, len;
    int i;
    if(L->size==0)
        return;
    else{
        maxL=maxR=0;
        maxLen = 1;
    }
    l=r=0;
    len = 1;
    for(i=1; i<L->size; i++){
        if(L->Data[i]>L->Data[i-1]){
            r++;
            len++;
        }
        else{ /*遇到非增长点更新*/
            if(len>maxLen){
                maxL = l;
                maxR = r;
                maxLen = len;
            }
            l=r=i;
            len = 1;
        }
    }
    if(len>maxLen){ /*遍历结束后再次判断以防遗漏*/
        maxL = l;
        maxR = r;
        maxLen = len;
    }

    for(i=maxL; i<=maxR; i++){
        if(i==maxL)
            printf("%d", L->Data[i]);
        else
            printf(" %d", L->Data[i]);
    }
}

习题3.6 一元多项式的乘法与加法运算 (20分)

#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
struct poly
{
    int a,b;
}r1[1000],r2[1000];
int ans[1000000],ant = 0;
int main()
{
    int a,b,flag = 0,e;
    cin>>a;
    for(int i = 0;i < a;i ++)
    {
        cin>>r1[i].a>>r1[i].b;
    }
    cin>>b;
    for(int i = 0;i < b;i ++)
    {
        cin>>r2[i].a>>r2[i].b;
    }
    map<int,int>p,q;
    for(int i = 0;i < a;i ++)
    {
        for(int k = 0;k < b;k ++)
        {
            if(p[r1[i].b + r2[k].b] == 0)ans[ant ++] = r1[i].b + r2[k].b;
            p[r1[i].b + r2[k].b] += r1[i].a*r2[k].a;
        }
    }
    e = 0;
    sort(ans,ans+ant);
    for(int i = ant - 1;i >= 0;i --)
    if(p[ans[i]])
    {
        e ++;
        if(flag)cout<<' '<<p[ans[i]]<<' '<<ans[i];
        else
        {
            cout<<p[ans[i]]<<' '<<ans[i];
            flag = 1;
        }
    }
    if(e == 0)cout<<0<<' '<<0;
    cout<<endl;
    ant = 0;
    e = 0;
    for(int i = 0;i < a;i ++)
    {
        if(q[r1[i].b] == 0)ans[ant ++] = r1[i].b;
        q[r1[i].b] += r1[i].a;
    }
    for(int i = 0;i < b;i ++)
    {
        if(q[r2[i].b] == 0)ans[ant ++] = r2[i].b;
        q[r2[i].b] += r2[i].a;
    }
    if(ant == 0)cout<<0<<' '<<0;
    sort(ans,ans+ant);
    flag = 0;
    for(int i = ant - 1;i >= 0;i --)
    if(q[ans[i]])
    {
        e ++;
        if(flag)cout<<' '<<q[ans[i]]<<' '<<ans[i];
        else
        {
            flag = 1;
            cout<<q[ans[i]]<<' '<<ans[i];
        }
    }
    if(e == 0)cout<<0<<' '<<0;
}

习题3.8 符号配对 (20分)

#include<stdio.h>
#define MaxSize 100
struct stack{
    char elem[MaxSize];
    int top;
};
typedef struct stack seqstack;
int push(seqstack *s,char c);
int pop(seqstack *s,char *x);
int gettop(seqstack *s,char *x);
void InitStack(seqstack *s);
int match(char c1,char c2);


void InitStack(seqstack *s)
{
    s->top=-1;
}

int push(seqstack *s,char c)
{
    if(s->top==MaxSize-1)
        return 0;
    else{
        s->elem[++s->top]=c;
            return 1;
    }
}

int pop(seqstack *s,char *x){
    if(s->top==-1)
        return 0;
    else{
        *x=s->elem[s->top--];//这里用的*x
        return 1;
    }
}
 int gettop(seqstack *s,char *x)
 {
     if(s->top==-1)
        return 0;
     else{
        *x=s->elem[s->top];
        return 1;
     }
 }

int main()
{
   seqstack s;
     char ch;
     int i=0;
     InitStack(&s);
    char str[1000];
    while(gets(str))
    {
         if(str[0]=='.'&&str[1]==0)//这里有个跳出循环
            break;
            for(i=0;str[i]!='\0';i++){
        switch(str[i])
        {
        case '(':
        case '{':
        case '[':
            push(&s,str[i]);
            break;
        case '/':
            if(str[i+1]=='*'){
                push(&s,str[i]);
                push(&s,str[i+1]);
            }
            i+=1;
            break;
        case ')':
        case '}':
        case ']':
        case '*':
            if(s.top==-1)
            {
                printf("NO\n");
                switch(str[i])
                {
                case ')':
                    printf("?-)");
                    break;
                case '}':
                    printf("?-}");
                    break;
                case ']':
                    printf("?-]");
                    break;
                case '*':
                    if(str[i]=='*'&&str[i+1]=='/')
                        printf("?-*/");
                    break;
                }
                return 0;
            }
            else{
                gettop(&s,&ch);
                if(match(ch,str[i]))
                {
                  pop(&s,&ch);
                }
               else if(str[i]=='*')//*  字符 做单独处理
                {
                    if(ch=='*'&&str[i+1]=='/')// 是*/的符号
                    {
                        pop(&s,&ch);
                    pop(&s,&ch);
                    i++;
                    }
                    else//只是单一的 * 号
                    {
                        continue;
                    }
                }
                else
                {
                    printf("NO\n");
                    switch(ch)
                    {
                    case '{':
                        printf("{-?");
                        break;
                    case '(':
                        printf("(-?");
                        break;
                    case '[':
                        printf("[-?");
                        break;
                    case '*':
                        printf("/*-?");
                        break;
                    }
                    return 0;
                }
            }
        }
            }
    }
    if(s.top==-1)
        printf("YES\n");
    else{
       printf("NO\n");
                    switch(ch)
                    {
                    case '{':
                    
                        printf("{-?");
                        break;
                    case '(':
                        printf("(-?");
                        break;
                    case '[':
                        printf("[-?");
                        break;
                    case '*':
                        printf("/*-?");
                        break;
                    }
                    return 0;
    }
}
int match(char c1,char c2)
{
    switch(c1)
    {
    case '(':
        if(c2==')')
            return 1;
        else
            return 0;
            break;
    case '[':
        if(c2==']')
            return 1;
        else
            return 0;
            break;
    case '{':
        if(c2=='}')
            return 1;
        else
            return 0;
            break;
    default:
        return 0;
    }
}

习题3.9 堆栈操作合法性 (20分)

#include<stdio.h>
typedef enum{false,true} bool;
bool Judge(int N);
int main()
{
	int L;//number of line
	int N;//max of stack
	int flag=1;//adjust output
	scanf("%d %d\n", &L, &N);
	while (L--) {
		if (Judge(N)) {
			if (flag) flag = 0;
			else printf("\n");
			printf("YES");
		}
		else {
			if (flag) flag = 0;
			else printf("\n");
			printf("NO");
		}
	}
	return 0;
}
bool Judge(int N) {
	char temp;//temp storage of getchar
	int stack = 0;//number of stack
	int flag = 1;//1-true,0-false
	temp = getchar();//the first one
	while (temp != '\n'&&temp != '\0') {
		if (temp == 'S'&&stack<N) stack++;
		else if (temp == 'S'&&stack == N) flag = 0;
		else if (!stack) flag = 0;
		else stack--;
		temp = getchar();
	}
	if(stack) flag=0;
	if (flag) return true;
	else return false;
}

习题3.10 汉诺塔的非递归实现 (25分)

#include<stdio.h>
#include<stdlib.h>
typedef struct Node* pNode;
struct Node {
	int cnt;
	char start;
	char pass;
	char end;
};
typedef struct stack* pstack;
struct stack {
	pNode data;
	pstack next;
};
typedef struct list* plist;
struct list {
	pstack head;
};
plist newlist(void);
pstack firststack(int N);
void pop(plist L);
void trinode(plist L);
int main()
{
	int N, i, flag = 1;
	scanf("%d", &N);
	plist L = newlist();
	L->head->next = firststack(N);
	while (L->head->next) {
		if (L->head->next->data->cnt==1) {
			if (flag) flag = 0;
			else printf("\n");
			pop(L);
		}
		else {
			trinode(L);
		}
	}
	return 0;
}
plist newlist(void) {
	plist L = (plist)malloc(sizeof(struct list));
	L->head = (pstack)malloc(sizeof(struct stack));
	L->head->next = NULL;
	return L;
}
pstack firststack(int N) {
	pstack S = (pstack)malloc(sizeof(struct stack));
	S->next = NULL;
	S->data = (pNode)malloc(sizeof(struct Node));
	S->data->cnt = N;
	S->data->start = 'a';
	S->data->pass = 'b';
	S->data->end = 'c';
	return S;
}
void pop(plist L) {
	printf("%c -> %c", L->head->next->data->start, L->head->next->data->end);
	pstack p = L->head->next;
	L->head->next = p->next;
	free(p);
}
void trinode(plist L) {
	pstack p = L->head->next;
	p->data->cnt--;
	char temp = p->data->start;
	p->data->start = p->data->pass;
	p->data->pass = temp;
	pstack p1 = (pstack)malloc(sizeof(struct stack));
	pstack pn = (pstack)malloc(sizeof(struct stack));
	pn->next = p1;
	p1->next = p;
	L->head->next = pn;
	pn->data = (pNode)malloc(sizeof(struct Node));
	p1->data = (pNode)malloc(sizeof(struct Node));
	pn->data->cnt = p->data->cnt;
	p1->data->cnt = 1;
	p1->data->start = p->data->pass;
	p1->data->pass = p->data->start;
	p1->data->end = p->data->end;
	pn->data->pass = p1->data->end;
	pn->data->end = p1->data->pass;
    pn->data->start = p1->data->start;
}

习题3.11 表达式转换 (25分)

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

typedef struct snode *stack;
struct snode{
    char ch[20];
    int top;
};

stack CreateStack(); //创建堆栈
void push(stack s,char c); //入栈
char pop(stack s); //出栈

int main()
{
    char ch1[150]; //用来存储符号优先级
    ch1['(']=0;
    ch1['+']=1;
    ch1['-']=1;
    ch1['*']=2;
    ch1['/']=2;
    char s[21]; //用来存储中缀表达式
    scanf("%s",s);
    int l=strlen(s);
    stack st=CreateStack();
    int flag=0; //该标志位用来控制格式输出
    for(int i=0;i<l;i++) //遍历中缀表达式符号
    {
        if(s[i]=='(')
        {
            push(st,s[i]);
        }
        else if(s[i]==')')
        {
            char t;
            t=pop(st);
            while(t!='(')
            {
                printf(" %c",t);
                t=pop(st);
            }
            flag=1;
        }
        else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/')
        {
            if(s[i]=='+'&&(s[i-1]=='('||i==0));//如果这个+表示正号,不进行操作
            else if(s[i]=='-'&&(s[i-1]=='('||i==0))//如果这个-表示负号,直接输出
            {
                printf("-");
            }
            else if(ch1[s[i]]>ch1[st->ch[st->top]]||st->top==-1)
            {
                push(st,s[i]);
                flag=1;
            }
            else
            {
                printf(" %c",pop(st));
                while(ch1[s[i]]<=ch1[st->ch[st->top]]&&st->top!=-1)
                {
                    printf(" %c",pop(st));
                }
                push(st,s[i]);
                flag=1;
            }
        }
        else //运算数直接输出(包含小数.)
        {
            if(flag)
            {
                printf(" ");
                flag=0;
            }
            printf("%c",s[i]);
        }
    }
    while(st->top!=-1)//输出堆栈中剩余的符号
    {
        printf(" %c",pop(st));
    }
    return 0;
}

stack CreateStack()
{
    stack s=(stack)malloc(sizeof(struct snode));
    s->top=-1;
    return s;
}

void push(stack s,char c)
{
    (s->top)++;
    s->ch[s->top]=c;
}

char pop(stack s)
{
    return s->ch[(s->top)--];
}

练习4.1 根据后序和中序遍历输出先序遍历 (25分)

#include<stdio.h>
#include<string.h>
int m[10000];
int e[10000];
int str[100000]; 
void find(int root,int start,int end);
int main()
{
	int n,i;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&e[i]);
	}
	for(i=0;i<n;i++)
	{
		scanf("%d",&m[i]);
	}
	find(n-1,0,n-1);
	printf("Preorder: ");
	for(i=0;i<n-1;i++)
	printf("%d ",str[i]);
	printf("%d",str[n-1]); 
	return 0;
}
int sign=0;
void find(int root,int start,int end)
{
	if(start > end)
	return;
    int i = start;
    while(i<end && m[i]!=e[root])
	i++;
    str[sign++]=m[i];
    find(root-(end-i+1), start, i-1);
    find(root-1, i+1, end);
	
}

练习4.2 平衡二叉树的根 (25分)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
 
struct AVLNode{
	int Data;       /*结点数据*/
	AVLNode * Left; /*指向左子树*/
	AVLNode * Right;/*指向右子树*/
	int Height;     /*树高*/
};
 
typedef struct AVLNode * Position;/*定义结构体指针别名为Position*/ 
typedef Position AVLTree;
 
int Max(int a, int b)
{
	return a > b ? a:b;
}
 
int GetHeight(AVLTree A)
{/*获取结点A的高度*/
	int L,R;
	
	if(A){
		L=GetHeight(A->Left);/*求左子树的高度*/
		R=GetHeight(A->Right);/*求右子树的高度*/
		return L>R ? (L+1):(R+1);
	}
	
	else return 0;/*空树高度为0*/
}
 
AVLTree SingleLeftRotation(AVLTree A)
{/*左单旋,顺时针*/ 
	AVLTree B=A->Left;
	A->Left = B->Right;
	B->Right = A;
	A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
	B->Height = Max(GetHeight(B->Left), A->Height) + 1;
	
	return B;
}
 
AVLTree SingleRightRotation(AVLTree A)
{
	AVLTree B=A->Right;
	A->Right = B->Left;
	B->Left = A;
	A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
	B->Height = Max(GetHeight(B->Right), A->Height) + 1;
	
	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 T, int X)
{/*将X插入AVL树T中,并且返回调整后的AVL树*/ 
	if(!T){ /*若插入空树,则新建包含一个结点的树*/
		//T=(AVLTree)malloc(sizeof(struct AVLNode));
		T=new AVLNode;
		T->Data = X;
		T->Height = 1;
		T->Left = T->Right = NULL;	
	} /*if(插入空树)结束*/
	
	else if( X < T->Data ){
		/*插入T的左子树*/
		T->Left = Insert ( T->Left ,X);
		/*如果需要左旋*/
		if(GetHeight(T->Left)-GetHeight(T->Right)==2)
			if(X<T->Left->Data)
				T=SingleLeftRotation(T);    /*左单旋*/
			else
				T=DoubleLeftRightRotation(T);    /*左-右双旋*/
	} /*else if(插入左子树)结束*/
	
	else if (X>T->Data){
		/*插入T的右子树*/
		T->Right = Insert ( T->Right ,X);
		/*如果需要右旋*/
		if(GetHeight(T->Left)-GetHeight(T->Right)==-2)
			if(X>T->Right->Data)
				T=SingleRightRotation(T);    /*右单旋*/
			else
				T=DoubleRightLeftRotation(T);    /*右-左双旋*/
	} /*else if(插入右子树)结束*/
	
	/*else X==T->Data, 无需插入 */
	
	/*别忘了更新树高*/
	T->Height = Max(GetHeight(T->Left), GetHeight(T->Right))+1;
	
	return T;	
}
 
int main(){
	int n,x;
	AVLTree A=NULL;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&x);
		A=Insert(A,x);	
	}
	printf("%d\n",A->Data);
	return 0;	
}

练习4.3 堆中的路径 (25分)

#include <cstdio>
#include <cstdlib>
#define MAX 1001
#define MINH -10001
 
int H[MAX],size;
 
void  Create() { //建立空堆
    size = 0;
    H[0] = MINH;    //设置哨兵
}
void insert(int X) { //把X放于最后逐个与它的父节点进行比较,很巧妙!
    int i;
    for(i = ++size; H[i/2] > X; i /= 2)
        H[i] = H[i/2];
    H[i] = X;
}
 
int main() {
    int N, M, temp, j;
    scanf("%d%d", &N, &M);
    Create();
    for(int i = 0; i < N; i++) {
        scanf("%d", &temp);
        insert(temp);
    }
    for(int i = 0; i < M; i++) {
        scanf("%d", &j);
        printf("%d", H[j]);
        while(j > 1) {              //每次坐标除以2得到它的父节点,并输出就是路径
            j /= 2;
            printf(" %d", H[j]);
        }
        printf("\n");
    }
    return 0;
}

习题4.5 顺序存储的二叉树的最近的公共祖先问题 (25分)

#include <cstdio>
using namespace std;
int k;
int findroot(int a[],int x,int y)
{
    while(1)
    {
        if(x>y)
        {
            x/=2;
        }
        else
        {
            y/=2;
        }
        if(x==y)
        {
            k=x;
            return a[x];
        }
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        k=-1;
        int a[1010];
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        int x,y;
        scanf("%d %d",&x,&y);
        int ans=findroot(a,x,y);
        if(x==y)
        {
            printf("%d %d\n",x,a[x]);
        }
        else if(a[x]==0)
        {
            printf("ERROR: T[%d] is NULL\n",x);
        }
        else if(a[y]==0)
        {
            printf("ERROR: T[%d] is NULL\n",y);
        }
        else
        {
            printf("%d %d\n",k,ans);
        }
    }
}

习题5.13 词频统计 (30分)

#include <iostream>
#include <map>
#include <set>
#include <string>
using namespace std;

struct Node {
	string str;
	int count;
	bool operator<(const Node& s)const {
		return count == s.count ? str<s.str : count>s.count;
	}
};

int main() {
	set<Node>st;
	map<string, int>mp;
	string s;
	char c;
	while (scanf("%c", &c) && c != '#') {
		if (isalnum(c) || c == '_') {
			if (isalpha(c))
				c = tolower(c);
			s += c;
		}
		else if (s.size()) {
			if (s.size() > 15)
				s = s.substr(0, 15);
			mp[s]++;
			s.clear();
		}
	}
	for (auto& it : mp)
		st.insert({ it.first,it.second });
	int cnt = st.size();
	cout << cnt << endl;
	cnt /= 10;
	for (auto& it : st) {
		cout << it.count << ":" << it.str << endl;
		if (!--cnt)
			break;
	}
	return 0;
}

实例6.1 六度空间 (30分)

#include <stdio.h>
#include <stdbool.h>

#define SIX 6

int Graph[1001][1001], Queue[1001], N;
bool Visited[1001];

void Reset()
{
	int i;
	for (i = 1; i <= N; i++) {
		Visited[i] = false;
	}
}

void Read()
{
	int M, i, j;

	scanf("%d %d", &N, &M);
	for (i = 1; i <= N; i++) {
		Visited[i] = false;
		for (j = 1; j <= N; j++) {
			Graph[i][j] = 0;
		}
	}
	
	while (M--) {
		scanf("%d %d", &i, &j);
		Graph[i][j] = 1;
		Graph[j][i] = 1;
	}
}

int BFS(int V)
{
	int Front, Rear, Vertex, Tail, Last, Count, Level;
	int i;
	
	if (!Visited[V]) {
		Front = Rear = 0;
		Level = 0, Count = 1, Last = V;
		Visited[V] = true;
		Queue[Rear++] = V;
		while (Front != Rear) {
			Vertex = Queue[Front++];
			for (i = 1; i <= N; i++) {
				if (Graph[Vertex][i] && !Visited[i]) {
					Visited[i] = true;
					Queue[Rear++] = i;
					Tail = i;
					Count++;
				} 
			}
			if (Vertex == Last) {
				Level++;
				Last = Tail;
			}
			if (Level == SIX) {
				break;
			}
		}
	}
	
	return Count;
}

void Print(int V, int Count)
{
	printf("%d: %.2f%%\n", V, (double)(Count * 100) / (double) N);
}

void Compute()
{
	int i;
	
	for (i = 1; i <= N; i++) {
		Print(i, BFS(i));
		Reset();
	}
}

int main()
{
	//freopen("E:in.txt", "r", stdin);
		
	Read();
	Compute();
}

练习7.1 排序 (25分)

#include<stdio.h>
#include<stdlib.h>
void InsertationSort(int A[],int n);
void PrecDown(int A[],int p,int n);
void HeapSort(int A[],int n);
int main()
{
    int N,*A;
    scanf("%d",&N);
    A=(int *)malloc(sizeof(int)*N);
    for(int i=0;i<N;i++)
    {
        scanf("%d",&A[i]);
    }
    if(N<100)
    {
        InsertationSort(A,N);
    }
    else
    {
        HeapSort(A,N);
    }
    printf("%d",A[0]);
    for(int i=1;i<N;i++)
    {
        printf(" %d",A[i]);
    }
    return 0;
}
 
void InsertationSort(int A[],int n)
{
	int i,j;
    for(i=1;i<n;i++)
    {
    	int temp=A[i];
        for(j=i;j>0&&A[j-1]>temp;j--)
        {
            A[j]=A[j-1];
        }
        A[j]=temp;
    }
}
//下滤
void PrecDown(int A[],int p,int n)
{
    int parent,child,X;
    X=A[p];
    for(parent=p;(2*parent+1)<n;parent=child)
    {
        child=2*parent+1;
        if(A[child]<A[child+1]&&child!=n-1)
        {
            child++;
        }
        if(X>=A[child])
        {
            break;
        }
        else
        {
            A[parent]=A[child];
        }
    }
    A[parent]=X;
}
void HeapSort(int A[],int n)
{
    for(int i=n/2-1;i>=0;i--)//建立最大堆
    {
        PrecDown(A,i,n);
    }
    //把最大值换到最后
    for(int i=n-1;i>0;i--)
    {
        int temp;
        temp=A[0];
        A[0]=A[i];
        A[i]=temp;
        PrecDown(A,0,i);
    }
}

习题8.1 银行排队问题之单队列多窗口服务 (25分)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
typedef struct
{
    double start;
    double ends;
    double wait;
}Person;
 
typedef struct
{
    int num;
    Person List[1005];
}Window;
 
int main()
{
    int n, k;
    double s, e, time = 0, Min_time = 0, Maxtime = 0;
    Window all[15];
    Person store[10000];
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%lf %lf", &s, &e);
        if(e > 60){e = 60;}
        store[i].start = s, store[i].ends = e + s;
    }
    scanf("%d", &k);
    for(int i = 0 ; i < k; i++)
    {
        all[i].num = 0;
        all[i].List[0].ends = 0;
    }
    for(int i = 0; i < n; i++)
    {
        double mintime = 0;
        int place = 0;
        for(int j = 0; j < k; j++)
        {
            if(!j)
            {
                int num = all[j].num - 1;
                mintime = all[j].List[num].ends - store[i].start;
                if(mintime < 0)
                {
                    mintime = 0;
                }
                place = j;
                //printf("%lf %d %lf\n", mintime, all[j].List[num].ends - store[i].start, place);
                //printf("%lf %lf\n", all[j].List[num].ends, store[i].start);
            }
            else
            {
                int num = all[j].num - 1;
                double time = all[j].List[num].ends - store[i].start;
                if(time < 0)
                {
                    time = 0;
                }
                if(mintime > time)
                {
                    mintime = time;
                    place  = j;
                }
                //printf("++%lf %d %lf\n", mintime, all[j].List[num].ends - store[i].start, place);
                //printf("%lf %lf\n", all[j].List[num].ends, store[i].start);
            }
            //printf("%lf %d\n", mintime, place);
        }
 
        int num = all[place].num;
 
        all[place].num++;
        //printf("%d %d\n", place, all[place].num);
        all[place].List[num].start = store[i].start + mintime;
 
        all[place].List[num].wait = mintime;
 
        all[place].List[num].ends = store[i].ends + mintime;
        //printf("%lf %lf\n", all[place].List[num].ends, all[place].List[num].start);
 
        if(!i)
        {
            Min_time = mintime;
            Maxtime = store[i].ends + mintime;
        }
        else
        {
            if(mintime > Min_time)
            {
                Min_time = mintime;
            }
            if(Maxtime < store[i].ends + mintime)
            {
                Maxtime = store[i].ends + mintime;
            }
        }
        time += mintime;
    }
    printf("%.1lf %.lf %.lf\n", time / n, Min_time, Maxtime);
    for(int i = 0; i < k; i++)
    {
        if(i)
        {
            printf(" ");
        }
        printf("%d", all[i].num);
    }
    printf("\n");
    return 0;
}

习题8.2 银行排队问题之单队列多窗口加VIP服务 (30分)

#include <bits/stdc++.h>
struct consumer
{
	double arrive;
	double process;
	double start;
	double end;
	double wait;
	int vip;
	int skip;
}c[1001];
struct windows
{
	int count;
	int availiable;
	double end;
}w[11];
using namespace std;
int main()
{
	memset(c,0,sizeof(c));
	memset(w,0,sizeof(w));
	int n,k,arrive,process,vip;
	cin>>n;
	for (int i=0;i<n;i++)
	{
		cin>>arrive>>process>>vip;
		if (process>60) process=60;
		c[i].arrive=arrive;
		c[i].process=process;
		c[i].vip=vip;
	}
	int v;
	cin>>k>>v;
	for (int i=0;i<k;i++) w[i].availiable=1;
	int count=0;
	int m;
	for (m=0;;m++)
	{
		if (count==n) break;
		for (int i=0;i<k;i++)   //窗口刷新 
		{
			if (w[i].end==m)
			{
				w[i].availiable=1;
			}
		}
		if (w[v].availiable==1)    //vip窗口拉人 
		{
			for (int i=0;c[i].arrive<=m&&i<n;i++)
			{
				if (c[i].skip==1) continue;
				if (c[i].vip==1)
				{
					c[i].skip=1;
					c[i].start=m;
					c[i].end=c[i].start+c[i].process;
					c[i].wait=c[i].start-c[i].arrive;
					w[v].availiable=0;
					w[v].end=m+c[i].process;
					count++;
					w[v].count++;
					break;
				}
			}
		}
		for (int i=0;i<k;i++)
		{
			if (w[i].availiable==1)
			{
				for (int j=0;j<n&&c[j].arrive<=m;j++)
				{
					if (c[j].skip==1) continue;
					c[j].start=m;
					c[j].end=c[j].start+c[j].process;
					c[j].skip=1;
					c[j].wait=c[j].start-c[j].arrive;
					w[i].availiable=0;
					w[i].count++;
					w[i].end=m+c[j].process;
					count++;
					break;
				}
			}
		}
	}
	double sum=0;
	int maxwait=-1,last=-1;
	for (int i=0;i<n;i++)
	{
		sum+=c[i].wait;
		if (c[i].wait>maxwait)
		{
			maxwait=c[i].wait;
		}
		if (c[i].end>last)
		{
			last=c[i].end;
		}
//		printf("*%.1lf %.1lf %.1lf\n",c[i].start,c[i].process,c[i].end);
	}
	printf("%.1lf %d %d\n",sum/n,maxwait,last);
	printf("%d",w[0].count);
	for (int i=1;i<k;i++)
	{
		printf(" %d",w[i].count);
	}
	return 0;
}

习题8.3 银行排队问题之单窗口“夹塞”版 (30分)

#include <iostream>
#include <map>
#include <queue>
#include <cstdio>

using namespace std;

#define MaxNameLen 3
#define MaxPeopleNum 10000

typedef struct People ElementType;
typedef int Position;
struct People {
	int T;
	int P;
	char Name[MaxNameLen + 1];
	Position Index;
} PQueue[MaxPeopleNum];

int main() 
{
	//freopen("E:in.txt", "r", stdin);
	map<string, int> Group;
	queue<ElementType> Que;
	char Name[MaxNameLen + 1];
	int N, M, L, i, j;
	
	scanf("%d %d", &N, &M);
	for (i = 0; i < M; i++) {
		scanf("%d", &L);
		for (j = 0; j < L; j++) {
			scanf("%s", Name);
			Group[Name] = i;
		}
	}
	for (i = 0; i < N; i++) {
		scanf("%s %d %d", &PQueue[i].Name, &PQueue[i].T, &PQueue[i].P);
		if (PQueue[i].P > 60) {
			PQueue[i].P = 60;
		} 
		PQueue[i].Index = i;
		Que.push(PQueue[i]);
	}
	
	int CurrentTime, SumWaitTime, WindowsTime, WaitTime;
	ElementType X;
	bool Visited[N] = {false};
		
	CurrentTime = SumWaitTime = WindowsTime = WaitTime = 0;
	while (!Que.empty()) {
		X = Que.front();
		Que.pop();
		if (!Visited[X.Index]) {  //如果没有被删除 
			Visited[X.Index] = true;
			printf("%s\n", X.Name);
			CurrentTime += WindowsTime; //解决掉上一个事务 
			if (X.T <= CurrentTime) {   //如果顾客提前来到,累加等待时间 
				WaitTime = CurrentTime - X.T;
				SumWaitTime += WaitTime;
			} else {
				CurrentTime = X.T;  //否则更新当前时间,为顾客到达时间 
			} 
			WindowsTime = X.P; //添加当前事务
			for (i = X.Index + 1; i < N; i++) {
				if (!Visited[i] && Group.count(X.Name) && Group.count(PQueue[i].Name) && (Group[X.Name] == Group[PQueue[i].Name])) {  //判断是否在同一个朋友圈 
					if (CurrentTime + WindowsTime >= PQueue[i].T) {  //如果当前事务完成前,朋友已经来到,帮助朋友 
						SumWaitTime += (CurrentTime + WindowsTime - PQueue[i].T);  //累加朋友等待时间 
						Visited[i] = true;
						printf("%s\n", PQueue[i].Name);
						WindowsTime += PQueue[i].P;
					}
				}
			}
		}		
	}
	
	printf("%.1f", (double)SumWaitTime / (double)N);
	
    //fclose(stdin);
    return 0;
}

习题8.4 畅通工程之最低成本建设问题 (30分)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

struct city
{
	int x;
	int y;
	int money;
}a[4010];

int find_root(int root, int f[])
{
	int dd = root;
	while(root != f[root])
		root = f[root];
		
	while(dd != root)
	{
		int t = f[dd];
		f[dd] = root;
		dd = t;
	}
	return root;
}
bool cap(city a, city b)
{
	return a.money < b.money;
} 
int main()
{
	int n, m;
	
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		int t = n;
		n = m;
		m = t;
		
		int f[5010] = {0};
		if(n == 0)
		break;
		
		for(int i = 1; i <= m; i++)
			f[i] = i;
		for(int i = 1; i <= n; i++)
		{
			scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].money);
		}
		
		if(n < m-1)
			printf("?\n");
		else
		{
			int sum = 0, flag = 1;
			sort(a + 1, a + 1 + n, cap);
			
			for(int i = 1; i <= n; i++)
			{
				if(find_root(a[i].x, f) != find_root(a[i].y, f))
				{
					f[find_root(a[i].x, f)] = find_root(a[i].y, f);
					sum += a[i].money;
				}	
			}
			for(int i = 1; i <= m; i++)
				f[i] = find_root(i, f);
			
			int ans = 0;
			
			for(int i = 1; i <= m; i++)
				if(i == f[i])
				{
					ans++;
					if(ans >= 2)
					{
						flag = 0;
						break;
					}
				}
				
			if(flag)
				cout<<sum<<endl;
			else
				cout<<"Impossible"<<endl;
		}
	}
	return 0;
} 

习题8.5 畅通工程之局部最小花费问题 (35分)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <math.h>
#include <stack>
#include <utility>
#include <string>
#include <sstream>
#include <cstdlib>
#include <set>
#define LL long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 10000 + 10;
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
struct Edge
{
    int from;
    int to;
    int cost;
    Edge(int x = 0,int y = 0,int w = 0)
    {
        from = x;
        to = y;
        cost = w;
    }
} edge[maxn];
int par[1000];
int Find(int x)
{
    if(x == par[x])
        return x;
    else
        return par[x] = Find(par[x]);
}
bool cmp(Edge a,Edge b)
{
    return a.cost < b.cost;
}
int main()
{
    int m,n;
    scanf("%d",&m);
    n = m *(m - 1) / 2;
    for(int i = 0; i <= 1000; i++)
    {
        par[i] = i;
 
    }
    for(int i = 0; i < n; i++)
    {
        int index;
        scanf("%d %d %d",&edge[i].from,&edge[i].to,&edge[i].cost);
        scanf("%d",&index);
        if(index)
            edge[i].cost = 0;
    }
    sort(edge,edge+n,cmp);
    int sum = 0;
    for(int i = 0; i < n; i++)
    {
        int x = Find(edge[i].from);
        int y = Find(edge[i].to);
        if(x != y)
        {
            par[x] = y;
            sum+= edge[i].cost;
        }
 
    }
    printf("%d\n",sum);
    return 0;
}

END

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值