数据结构不难9

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; 
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352