数据结构不难9

2019-03-22  本文已影响0人  Archer_ll

2019/3/22更新:第一次更 没来得及写解题思路
————————————————————————

时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

翻转一个链表

特殊要求:请使用以下链表结构

class Node
{
int value;
Node next;
}

输入

输入包含多组数据。对于每组数据:

第一行是n,表示链表长度;当n=-1时,表示输入结束。(1 <= n <= 100)

第二行是n个整数,表示链表每一位所存储的内容。
输出

针对每组输入,输出翻转后的链表的内容。
样例输入

4
1 3 5 7
-1

样例输出

7 5 3 1

ac代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;

class ListNode
{
public:
    int val;
    ListNode *next;
    ListNode (int val)
    {
        this->val = val;
        this->next = NULL;
    }
};

int main()
{
    int n;
    while (1) {
        cin >> n;
        if (n == -1) break;
        ListNode dummy(0), *cur = &dummy;
        int val; 
        // construct the linked list
        for (int i = 0; i < n&&val!=-1; ++i) { 
            cin >> val;
            cur->next = new ListNode(val);
            cur = cur->next;
        }

        // reverse
        ListNode *head = dummy.next;
        ListNode *prev = NULL;
        while (head) {
            ListNode *next = head->next;
            head->next = prev;
            prev = head;
            head = next;
        }
        head = prev;

        // print
        while (head->next) {
            cout << head->val << " ";
            head = head->next;
        }
        cout << head->val << endl;
    }
}

第二题

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

<dl class="des">

描述

编写一个程序可以完成基本的带括号的四则运算。其中除法(/)是整除,并且在负数除法时向0取整。(C/C++/Java默认的除法就是向0取整,python默认的是向负无穷取整。)

例如计算 100 * ( 2 + 12 ) - (20 / 3) * 2, 结果是1388。

输入

一个长度不超过100的字符串,代表要计算的算式。包含数字0-9以及+-*/()。

输入保证计算过程不会超过32位有符号整数,并且其中的'-'都是减号没有负号。

输出

计算的结果。

样例输入

100*(2+12)-(20/3)*2

样例输出

1388

AC代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<stack>
using namespace std;
 
int getrink(char opt)
{
    if(opt == '+' || opt == '-') return 10;
    if(opt == '*' || opt == '/') return 20;
    if(opt == '(') return 0;
    else return -1;
}
 
int postfix(string &str_post,string &str_mid)
{
    stack<char> opt;
    while(!opt.empty()) opt.pop();
    bool flag=false;
    for(int i=0; str_mid[i]!='\0'; i++)
    {
        if(str_mid[i]>='0'&&str_mid[i]<='9')
        {
            if(flag)
            {
                str_post+='&';
            }
            else
            {
                flag=true;
            }
            while(str_mid[i]>='0'&&str_mid[i]<='9')
            {
                str_post+=str_mid[i];
                i++;
            }
            i--;
        }
        else if(str_mid[i]=='(')
        {
            opt.push(str_mid[i]);
        }
        else if(str_mid[i]==')')
        {
            if(!opt.empty()&&opt.top()!='(')
            {
                str_post+=opt.top();
                opt.pop();
                flag=false;
            }
            if(opt.top()=='(')
            {
                opt.pop();
            }
        }
        else if(str_mid[i]=='+'||str_mid[i]=='-'||str_mid[i]=='*'||str_mid[i]=='/')
        {
            int a1=getrink(str_mid[i]);
            int a2;
            while(!opt.empty())
            {
                a2=getrink(opt.top());
                if(a1<=a2)
                {
                    str_post+=opt.top();
                    opt.pop();
                    flag=false;
                }
                else
                {
                    break;
                }
            }
            opt.push(str_mid[i]);
        }
    }
    while(!opt.empty())
    {
        str_post+=opt.top();
        opt.pop();
    }
}
 
int getresult(int a,int b,char opp)
{
    if(opp=='+') return a+b;
    if(opp=='-') return a-b;
    if(opp=='*') return a*b;
    if(opp=='/') return a/b;
}
 
int compute(string str)
{
    int op1,op2,temp;
    stack<int> data;
    while(!data.empty()) data.pop();
    for(int i=0;str[i]!='\0';i++)
    {
        if(str[i]=='&') continue;
        else if(str[i]>='0'&&str[i]<='9')
        {
            temp=0;
            while(str[i]>='0'&&str[i]<='9')
            {
                temp=temp*10+str[i]-'0';
                i++;
            }
            i--;
            data.push(temp);
        }
        else if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')
        {
            op1=data.top();
            data.pop();
            op2=data.top();
            data.pop();
            temp=getresult(op2,op1,str[i]);
            data.push(temp);
        }
    }
    return data.top();
}
 
int main()
{
    string str_mid,str_post;
    while(cin>>str_mid)
    {
        postfix(str_post,str_mid);
        cout<<compute(str_post)<<endl;
        break;
    }
    return 0;
}

第四题

时间限制:5000ms
单点时限:1000ms
内存限制:256MB

描述

柱状图是由一些宽度相等的长方形下端对齐后横向排列得到的图形。

现在有由n个宽度为1,高度分别为h1,h2...hn的长方形从左到右依次排列组成的柱状图。问里面包含的长方形的最大面积是多少。

如高度 1 2 3 包含的最大长方形面积是4
输入

数字n和随后的n个数字,空格隔开
输出

最大面积
样例输入

7 2 1 4 5 1 3 3

样例输出

8

AC代码

#include <iostream> 
#include <cstdio> 
#include <cstring> 
#include <stack> 
#include <vector> 
#include <cmath> 
using namespace std; 
const int maxn = 100010; 
int n; 
int h[maxn],L[maxn],R[maxn]; 
int st[maxn]; 
void solve() 
{ 
    int t = 0; 
    for(int i=0;i<n;i++) 
    { 
        while(t>0 && h[st[t-1]] >= h[i]) 
            t--; 
        L[i] = t==0?0:(st[t-1]+1);
        st[t++] = i; 
    } 
    t = 0; 
    for(int i=n-1;i>=0;i--) 
    { 
        while(t > 0 && h[st[t-1]] >= h[i]) 
            t--; 
        R[i] = t == 0 ? n : st[t-1]; 
        st[t++] = i; 
    } 
    long long ans = 0; 
    for(int i=0;i<n;i++) 
    { 
        ans = max(ans , (long long)h[i]*(R[i]-L[i])); 
    } 
    printf("%lld\n",ans); 
}
int main() 
{ 
    while(scanf("%d",&n)==1 && n){

        for(int i=0;i<n;i++) 
            scanf("%d",&h[i]); 
        solve(); 
        break;
    }
    return 0; 
}

第五题

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

请你实现一个加强版的栈,支持以下操作:

push x: 向栈顶加入一个整数x

pop: 从栈顶弹出一个整数,并且输出该整数

inc k x: 将处于栈底的前k个整数加x。
输入

第一行包含一个整数N,代表操作的数量。

以下N行每行一条操作。

1 ≤ N ≤ 200000, 0 ≤ x ≤ 100000, 1 ≤ k ≤ 当前栈的大小
输出

对于每一个pop操作,输出弹出的整数数值。
样例输入

6  
push 1  
inc 1 2  
push 2  
inc 2 2  
pop  
pop

样例输出

4  
5

AC代码

#include <bits/stdc++.h>

using namespace std;

int sk[210000], top, fg[210000];

int main()
{
    int n, a, b;
    cin>>n;
    string op;
    top = -1;
    memset(fg, 0, sizeof(fg));
    while(n--){
        cin>>op;
        if(op=="push"){
            cin>>a;
            sk[++top] = a;
        }else if(op=="inc"){
            cin>>a>>b;
            fg[a-1] += b;
        }else if(op=="pop"){
            cout<<sk[top]+fg[top]<<endl;
            fg[top-1] += fg[top];
            fg[top] = 0;
            top--;
        }
    }

    return 0;
}

第六题

时间限制:5000ms
单点时限:1000ms
内存限制:256MB

描述

有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右滑动一个位置。

例如,数组为[4,3,5,4,3,3,6,7],窗口大小为3时:依次出现的窗口为[4,3,5], [3,5,4], [5,4,3], [4,3,3], [3,3,6], [3,6,7]。

如果数组长度是n,窗口大小是w,则一共产生n-w+1个窗口。
输入

第一行 n 和 w,空格隔开,n为数组长度,w为窗口宽度
第二行为n个整数,作为数组元素,空格隔开
输出

n-w+1个数,每个数是对应窗口中的最大值。

例如上面的例子,应该返回[5,5,5,4,6,7]。
样例输入

8 3
4 3 5 4 3 3 6 7

样例输出

5 5 5 4 6 7

AC代码

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

vector<int> fun(const vector<int> &vec, const int &n, const int &w) 
{ 
    vector<int> res; 
    deque<int> dq; 
    for (int i = 0; i<n; ++i) 
    { 
        if (dq.empty()) dq.push_back(vec[i]);
        //从队尾插入元素 
        else 
        { 
            while (!dq.empty()) 
            { 
                if (dq.back() >= vec[i]) break; 
                else
                    //如果队尾元素<下一个元素,则不断删除队尾元素(保证次最大值总是紧邻队头元素) 
                    dq.pop_back(); 
            } 
            dq.push_back(vec[i]);
            //如果队尾(有时候也是队头)元素>=下一个元素加入队尾 
        } 
        if (dq.size() >= w+1)
            //当前队列元素>=窗口大小,删除队头元素 
            dq.pop_front(); 
        if (i >= w -1) res.push_back(dq.front());
        //队头元素是滑动窗口的最大值 
    }
    return res; 
} 

int main() 
{ 
    int a,b;
    cin>>a>>b;
    int x[a];
    for (int i =0;i<a;i++){
        cin>>x[i];
    }
    vector<int> v1(x,x+a); 
    vector<int> v2 = fun(v1, a, b);
    int y = v2.size(); 
    for (int i = 0;i<y;i++){ 
        cout << v2[i] ;
        if (i!=y-1)
            cout<<" "; 
    } 
    return 0; 
}

上一篇下一篇

猜你喜欢

热点阅读