OJ每日刷题

每日一题,持续更新!
题目来源:PIPIOJ


7月9日

  1. 题目描述: PIPI给你一个合法的括号序列,希望跟你按左括号下标递增顺序给出每对括号在序列中的下标。(下标从1开始)
  2. 输入: 多组数据,请处理到EOF。对于每组数据,第一行包括一个只包含’(’,’)'的字符串,保证输入的括号匹配序列合法,长度不超过100000
  3. 输出: 按左括号下标递增顺序给出每对括号在序列中的下标。
  4. 样例输入: (())()()
  5. 样例输出:
    1 4
    2 3
    5 6
    7 8

思考:显然是需要用到栈的知识,遇到左括号入栈,遇到右括号,栈里面的左括号出栈匹配。

#include<bits/stdc++.h>
using namespace std;

//定义栈
#define MAXSIZE 100100
typedef struct Stack{
    int data[MAXSIZE];
    int top = -1;
}Stack;

int main(){
    Stack s;//声明一个栈
    int index[MAXSIZE];
    char k[MAXSIZE];
    while (scanf("%s",&k)!=EOF){
        int l = strlen(k);//计算字符串的长度
        for (int i = 0; i < l; ++i){
            if (k[i] == '('){ //遇到左括号,下标入栈
                s.data[++s.top]= i+1;
            } else { //遇到右括号,出栈,记录下标
                int j = s.data[s.top--];//匹配左括号的下标
                index[j] = i+1;
            }
        }

        for (int i = 0; i < l; ++i){
            if (index[i] !=0){
                printf("%d %d\n",i,index[i]);
                index[i] = 0;
            }
        }
    }
    return 0;
}

7月10日

  1. 题目描述
    从顺序表L中删除具有最小值的元素(假设唯一)并友函数返回被删元素的值。空出的元素由最后一个元素填补。
  2. 输入
    输入包含一个整数n代表顺序表L长度。
    接下来包含n个整数,代表顺序表L中的元素。
  3. 输出
    若顺序表为空,输出 “error”.
    若不为空,输出最小元素的值并输出删除最小值之后的顺序表。
  4. 样例输入
    3
    1 2 3
  5. 样例输出
    1
    3 2
#include<bits/stdc++.h>

using namespace std;

//定义顺序表
typedef struct SqList{
    int *data;
    int length;
}SqList;

int main(){
    SqList s;
    int min = 0;
    scanf("%d",&s.length);
    if (s.length <= 0){
        printf("error\n");
        return 0;
    }
    s.data = (int *)malloc(sizeof(int)*s.length);
    for (int i = 0; i < s.length; ++i){
        scanf("%d",&s.data[i]);
        if (s.data[i] < s.data[min]){
            min = i;
        }
    }
    int m = s.data[min];
    s.data[min] = s.data[s.length-1];
    s.length--;
    printf("%d\n",m);
    for (int i = 0; i < s.length; ++i){
        printf("%d ",s.data[i]);
    }
    printf("\n");

    return 0;
}
  1. 题目描述
    PIPI现在由一个顺序表L,他想把顺序表所有元素逆置,要求除了存储L的空间外,辅助的空间复杂度为O(1).
  2. 输入
    输入包含一个整数n代表顺序表L长度。
    接下来包含n个整数,代表顺序表L中的元素。
  3. 输出
    输出逆置后的顺序表
  4. 样例输入
    3
    1 2 3
  5. 样例输出
    3 2 1
#include<bits/stdc++.h>
using namespace std;

typedef struct SqList{
    int *data;
    int length;
}SqList;


int main(){
    SqList s;
    scanf("%d",&s.length);
    s.data = (int *) malloc(sizeof(int)*s.length);
    for (int i = 0; i < s.length; ++i){
        scanf("%d",&s.data[i]);
    }
    //逆置
    int l=0,r=s.length-1;
    int temp;
    while (r>l){
        temp = s.data[l];
        s.data[l] = s.data[r];
        s.data[r] = temp;
        l++;
        r--;
    }
    for (int i = 0; i < s.length; ++i){
        printf("%d ",s.data[i]);
    }
    printf("\n");
    free(s.data);
    return 0;
}

7月11日

  1. 题目描述
    长度为n的顺序表L,编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,删除线性表中所有值为x的数据元素。
  2. 输入
    输入包含一个整数n代表顺序表L长度,一个x代表要删除的元素。
    接下来包含n个整数,代表顺序表L中的元素。
  3. 输出
    输出删除元素x后的顺序表。
  4. 样例输入
    5 2
    1 3 2 5 2
  5. 样例输出
    1 3 5

思考:只需定义一个变量k统计不等于x的个数,并把这个不等于x的数放在第k个的位置。

#include<bits/stdc++.h>
using namespace std;

typedef struct SqList{
    int *data;
    int length;
}SqList;

int main(){
    SqList s;
    int d;
    scanf("%d",&s.length);
    scanf("%d",&d);
    s.data = (int *) malloc(sizeof(int) * s.length);
    for (int i = 0; i < s.length; ++i){
        scanf("%d",&s.data[i]);
    }
    //用k记录线性表L中 不等于 x的个数,边扫描,便统计k,不等于 x的元素移动到第k个位置上
    int k = 0;
    for (int i = 0; i < s.length; ++i){
        if (s.data[i] != d){
            s.data[k++] = s.data[i];
        }
    }
    s.length = k;
    for (int i = 0; i < s.length; ++i){
        printf("%d ",s.data[i]);
    }
    printf("\n");
    free(s.data);

    return 0;
}
  1. 题目描述
    假设一个算术表达式中包含圆括号,方括号,花括号3种类型的括号,编写算法来判别表达式中括号是否配对。
  2. 输入
    输入包含多组测试用例。
    对于每组测试样例,包括一个仅由 ‘(’,’)’,’[’,’]’,’{’,’}'组成的字符串s。
  3. 输出
    若s是合法的括号串,输出"yes",否则,输出"no"。
  4. 样例输入

    {()}(]
  5. 样例输出
    yes
    no
#include<bits/stdc++.h>
using namespace std;

//定义一个顺序栈
#define MAXSIZE 100100
typedef struct Stack{
    int data[MAXSIZE];
    int top;
}Stack;

int main(){
    Stack s;
    s.top = -1;
    char str[MAXSIZE];
    while(scanf("%s",&str)!=EOF){
        int len = strlen(str);
        for (int i = 0; i < len; ++i){
            //左括号入栈,右括号出栈
            if (str[i] == '(' || str[i] == '[' || str[i] == '{'){
                s.data[++s.top] = str[i];
            } else {
                char pop = s.data[s.top--];
                if (pop == '(' && str[i] == ')'){
                    continue;
                } else if (pop == '[' && str[i] == ']'){
                    continue;
                } else if (pop == '{' && str[i] == '}'){
                    continue;
                } else{
                    printf("no\n");
                    s.top = -3;
                    break;
                }
            }
        }

        if (s.top == -1){
            printf("yes\n");
        } else {
            if (s.top !=-3){
                printf("no\n");
            }
            s.top = -1;
        }

    }

    return 0;
}

7月12日

  1. 题目描述
    PIPI现在有一段由小写字母组成的文本s,他每天的工作就是找到文本中两个相邻并且相同的字母,然后删除它们。注意这个过程是递归的,比如:
    “abbac”->“aac”->“c”。
    返回PIPI删除的文本。
  2. 输入
    输入一行,代表文本s。(1<=|s|<=1e5).
  3. 输出
    输出一行,代表PIPI经过上述操作之后得到的文本。
  4. 样例输入
    abbbac
  5. 样例输出
    abac
#include<bits/stdc++.h>
using namespace std;

#define MaxSize 100000

int main(){
    char s[MaxSize];
    scanf("%s",&s);
    int len = strlen(s);
    int sum = 0;//记录相邻位置不相等的个数
    int sum2 = 0; // 上一次相邻位置不相等的个数
    while (true){
        int i = 1;
        for (i = 1; i < len; ++i){
            if(s[i-1] != s[i]){
                s[sum++] = s[i-1];
            } else {
                i++;
            }
        }
        if (i == len){
            s[sum++] = s[i-1];
        }
        if (sum==len ||sum == sum2 || sum == 1){
            break;
        } else {
            sum2 = sum;
            len = sum;
            sum = 0;
        }
    }
    len = sum;
    for (int i = 0; i < len; ++i){
        printf("%c",s[i]);
    }
    printf("\n");

    return 0;
}

7月13日

  1. 题目描述
    给定一个长度为n的单链表,删除倒数第K的节点,然后从头到尾输出每个节点的值。
  2. 输入
    第一行包含两个整数N,k,k<=N.
    第二行包含N个整数,代表从表头到表尾每个节点的值。
    你需要建立单链表把这N个数串起来~
  3. 输出
    按顺序输出删除了倒数第K个节点后每个节点的值。
  4. 样例输入
    5 2
    1 2 3 4 5
  5. 样例输出
    1 2 3 5
#include<bits/stdc++.h>
using namespace std;


//单链表
typedef struct ListNode{
    int data;
    struct ListNode *next;
}ListNode, *LinkedList;


int main(){
    //尾插法构造单链表
    LinkedList list;
    list = (ListNode *) malloc(sizeof(ListNode));
    list->next = NULL;
    ListNode *r = list;
    int n;
    int k;
    scanf("%d",&n);
    scanf("%d",&k);
    ListNode *p;//要插入的结点
    list->next = p;
    for (int i = 0; i < n; ++i){
        p = (ListNode *) malloc(sizeof(ListNode));
        scanf("%d",&p->data);
        r->next = p;
        r = p;
    }
    //最后一个结点指向NULL
    r->next = NULL;

    //删除

    //找到第n-k个
    ListNode *q = list;
    for (int i = 0; i < n-k; ++i){
        q = q->next;
    }
    //删除第n-k+1个
    ListNode *m = q->next;
    q->next= q->next->next;
    free(m);
    n--;
    q = list;
    for (int i = 0; i < n; ++i){
        q = q->next;
        printf("%d ",q->data);
    }

    printf("\n");
    return 0;
}

7月14日

  1. 题目描述
    反转长度为N的单链表从位置 L 到 R 的子段。请在常数空间复杂度下使用一趟扫描完成反转。
  2. 输入
    第一行三个整数N,L,R,1<=L<=R<=N
    接下来N个数表示N个节点的值
  3. 输出
    输出反转后的单链表节点值
  4. 样例输入
    5 2 4
    1 2 3 4 5
  5. 样例输出
    1 4 3 2 5

这题有代码有15%的错误,找了半天没找到,先保存一下代码,有时间再修改:

#include<bits/stdc++.h>
using namespace std;

//单链表
typedef struct ListNode{
    int data;
    struct ListNode *next;
}ListNode,*LinkedList;


int main(){
    int n,l,r;
    scanf("%d",&n);
    scanf("%d",&l);
    scanf("%d",&r);

    LinkedList list = (ListNode *) malloc(sizeof(ListNode));
    ListNode *t = list; //t指向尾结点,尾插法

    ListNode *s;
    for (int i = 0; i < n; ++i){
        s = (ListNode *) malloc(sizeof(ListNode));
        scanf("%d",&s->data);
        t->next = s;
        t = s;
    }
    t->next = NULL;

    //逆置链表

    //找到第l-1个结点
    ListNode *a = list;
    ListNode *p;
    for (int i = 0; i < l-1; ++i){
        a = a->next;
    }
    //第l个结点
    p = a->next;
    //保留第l个结点
    ListNode *b = p;
    ListNode *q = p->next,*m;
    for (int i = l; i < r; ++i){
        m = q->next;
        q->next = p;
        p = q;
        q = m;
    }
    b->next = m;
    a->next = p;

    ListNode *w= list->next;
    while (w != NULL){
        printf("%d ",w->data);
        w = w->next;
    }

    printf("\n");
    return 0;
}

7月15日

  1. 题目描述
    给定带头结点的单链表L,假设L存储了n个元素(n为奇数,是未知的)。设计算法返回该链表中间的那个元素。要求仅对链表进行一次遍历。
  2. 输入
    输入N个数字,不用关心N是多少,使用while循环读入链表中元素,直至EOF。(0<N≤1e5)
  3. 输出
    输出链表最中间的元素。
  4. 样例输入
    1 2 3 4 5
  5. 样例输出
    3
#include<bits/stdc++.h>
using namespace std;

//单链表
typedef struct ListNode{
    int data;
    struct ListNode *next;
}ListNode,*LinkedList;


int main(){
    LinkedList list = (ListNode *) malloc(sizeof(ListNode));
    int n;
    ListNode *r = list;
    ListNode *s;
    while (scanf("%d",&n)!=EOF){
        s = (ListNode *) malloc(sizeof(ListNode));
        s->data = n;
        r->next = s;
        r = s;
    }
    r->next = NULL;
    ListNode *p = list;
    ListNode *q = list;
    while (q && q->next){
        p = p->next;
        q = q->next->next;
    }

    printf("%d\n",p->data);

    return 0;
}

7月20日

  1. 题目描述
    给定一个二叉树,找出其最大深度。
    最大深度是从根节点到最远叶子节点的最长路径上的节点数量。
  2. 输入
    输入一行,按照先序输入一棵二叉树,其中空节点用 -1 表示。
  3. 输出
    输出一行代表二叉树的最大深度。
  4. 样例输入
    1 2 -1 -1 3 4 -1 -1 -1
  5. 样例输出
    3
#include<bits/stdc++.h>
using namespace std;

typedef struct BiNode{
    int data;
    struct BiNode *lchild;
    struct BiNode *rchild;
}*BiTree;

void CreateTree(BiTree &T){
    //按照先序序列创建一棵二叉树
    int data;
    scanf("%d",&data);
    if(cin.get()!='\n'){
        if(data==-1){
            T=NULL;
        }else{
            T=(BiTree)malloc(sizeof(BiNode));
            T->data=data;
            CreateTree(T->lchild);
            CreateTree(T->rchild);
        }
    }
}

// 通过后序递归遍历二叉树T求二叉树高度:LRN
int HeithByPostOrder(BiTree T){
    if(T==NULL) return 0;	// 空树
    int lh=HeithByPostOrder(T->lchild);	// 递归访问左子树
    int rh=HeithByPostOrder(T->rchild); 	// 递归访问右子树
    return (lh>rh?lh:rh) + 1; 				// 自己的高度等于子树中最大高度加1
}
int main(){
    BiTree T;
    CreateTree(T);
    printf("%d",HeithByPostOrder(T));
    return 0;
}

7月21日

  1. 题目描述
    已知线性表中的元素以递增序列排列,并以单链表作存储结构。设计算法删除表中所有值相同的多余元素(使得操作后的线性表中所有的值均不相同),同时释放被删结点空间,并分析算法的时间复杂度。
  2. 输入
    第一行输入一个正整数n,表示元素个数,n<=100。
    第二行输入n个正整数元素,保证元素以递增排列,元素的值<=100。
  3. 输出
    输出删除相同元素后的链表。
  4. 样例输入
    5
    1 1 3 4 4
  5. 样例输出
    1 3 4
#include<bits/stdc++.h>
using namespace std;

//单链表
typedef struct ListNode{
    int data;
    struct ListNode *next;
}ListNode,*LinkedList;

int main(){
    LinkedList L = (ListNode *) malloc(sizeof(ListNode));

    int n;
    cin>>n;

    //尾插法构造单链表
    ListNode *r = L;
    //要插入的结点
    ListNode *s;
    for (int i = 0; i < n; ++i){
        s = (ListNode *) malloc(sizeof(ListNode));
        cin>>s->data;
        r->next = s;
        r = s;
    }
    r->next = NULL;

    //第一个结点
    ListNode *p = L->next;
    //要删除的结点
    ListNode *m;
    while (p->next){
        if (p->data == p->next->data){
            //删除结点 p->next
            m = p->next;
            p->next = m->next;
            free(m);
        } else {
            p = p->next;
        }
    }
    ListNode *q = L->next;
    while (q){
        cout<<q->data<<" ";
        q = q->next;
    }
    cout<<endl;

    return 0;
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值