2021FALL《数据结构》EOJ习题集题解

内容纲要

有问题可以评论或者加我QQ478985071提出,感谢!

习题集链接:
https://acm.ecnu.edu.cn/contest/447/

本文将收录习题集中所有习题的题解,更新看心情,学期前更完,题号按照顺序排序,点目录直达。

1001. A+B Problem

https://acm.ecnu.edu.cn/contest/447/problem/1001/

题解

不会建议/remake

代码

#include<stdio.h>

int main(){
    int a, b;
    char ch;
    while (scanf("%d %d", &a, &b) != EOF)
        printf("%d\n", a + b);
    return 0;
}

1002. A+B Problem Templated

https://acm.ecnu.edu.cn/contest/447/problem/1002/

题解

我看不懂,但我会做。

代码

class Solution {
public:
    int solve(int a, int b) {
        return a+b;
    }
};

1003.数据结构开课啦

https://acm.ecnu.edu.cn/contest/447/problem/1003/

题解

下面语言记得选Text。

代码

数据结构
数据结构
数据结构
树
存储
多
多对多

1004. 线性表插入删除操作

https://acm.ecnu.edu.cn/contest/447/problem/1004/

题解

最好使用链表。这里讲一下链表:

  • 如果给定规模为n的输入,那么创建链表的操作耗时为O(n)
  • 插入位置为k的元素,耗时为O(k)
  • 删除位置为k的元素,耗时为O(k)
  • 查询位置为k的元素,耗时为O(k)

可以看到,对比顺序表,插入和删除操作的时间复杂度都是线性的,比顺序表依次移动元素要快很多。但相对的,查询操作比顺序表的O(1)复杂度要高。
看一眼数据规模为10^5,如果使用顺序表,肯定超时。

代码

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

typedef struct LinkedNode{
    int elem;
    struct LinkedNode* next;
}node;

node* newNode(int elem){
    node* p = (node*)malloc(sizeof(node));
    p->elem = elem;
    p->next = NULL;
    return p;
}

void createLinkedList(node* head, int n){
    head->elem = 0;
    head->next = NULL;
    node *p = head;
    for(int i = 0; i < n; i++){
        int tmp;
        cin>>tmp;
        node* pp = newNode(tmp);
        p->next = pp;
        p = p->next;
    }
}

void addNode(node* head, int n, int elem){
    node* p = head;
    for(int i = 0; i < n; i++){
        if(!(p->next)){
            return;
        }
        p = p->next;
    }
    node* addedNode = newNode(elem);
    node* tmp = p->next;
    p->next = addedNode;
    if(tmp)
        addedNode->next = tmp;
}

int deleteNode(node* head, int n){
    node* p = head;
    for(int i = 0; i < n-1; i++){
        if(!(p->next))
            return -1;
        p = p->next;
    }
    node* tmp = p->next;
    if(!tmp)
        return -1;
    int itm = tmp->elem;
    p->next = tmp->next;
    free(tmp);
    return itm;
}

int main(){
    node* head = (node*)malloc(sizeof(node));

    int n;
    cin>>n;
    createLinkedList(head, n);
    int q;
    cin>>q;
    for(int i = 0; i < q; i++){
        int cmd;
        cin>>cmd;
        if(cmd == 1){
            int k, x;
            cin>>k>>x;
            addNode(head, k, x);
        }
        if(cmd == 2){
            int k;
            cin>>k;
            cout<<deleteNode(head, k)<<endl;
        }
    }
    return 0;
}

1005. 线性表的比较

https://acm.ecnu.edu.cn/contest/447/problem/1005/

题解

不会建议/remake

代码

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

int cmp(vector<int> A, vector<int> B){
    int minlen = A.size() > B.size() ? B.size():A.size();
    int maxlen = A.size() > B.size() ? A.size():B.size();
    for(int i = 0; i < minlen; i++){
        if(A[i] < B[i])
            return -1;
        if(A[i] > B[i])
            return 1;
    }
    if(minlen == maxlen)
        return 0;
    return minlen == A.size()?-1:1;
}

int main(){
    vector<int> A, B;
    int m, n;
    cin>>m>>n;
    for(int i = 0; i < m; i++){
        int tmp;
        cin>>tmp;
        A.push_back(tmp);
    }
    for(int i = 0; i < n; i++){
        int tmp;
        cin>>tmp;
        B.push_back(tmp);
    }
    cout<<cmp(A, B)<<endl;
    return 0;
}

1006. 线性链表的插入与删除

https://acm.ecnu.edu.cn/contest/447/problem/1006/

题解

基本链表操作。看清楚题目要求,tar不是位置,是值。

代码

NODE* newNode(int data){
    NODE* p = (NODE*)malloc(sizeof(NODE));
    p->data = data;
    p->next = NULL;
    return p;
}

NODE* insertLinklist(NODE* head, int tar, int val){
    NODE* p = head;
    if(!head){
        NODE* addedNode = newNode(val);
        head = addedNode;
        return head;
    }
    while(p){
        if(p->data == tar)
            break;
        p = p->next;
    }
    NODE* addedNode = newNode(val);
    NODE* tmp = p->next;
    p->next = addedNode;
    if(tmp)
        addedNode->next = tmp;
    return head;
}

NODE* deleteLinklist(NODE* head, int tar){
    NODE* p = head;
    if(!head)
        return head;
    if(p->data == tar){
        p = p->next;
        head = p;
        return head;
    }
    while(p){
        if(p->next->data == tar)
            break;
        p = p->next;
    }
    NODE* tmp = p->next;
    if(!tmp)
        return head;
    int itm = tmp->data;
    p->next = tmp->next;
    free(tmp);
    return head;
}

1007. 环形双向链表的删除操作

https://acm.ecnu.edu.cn/contest/447/problem/1007/

题解

定义好双向环形链表的函数即可。注意将链表删空的情况。

代码

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

typedef struct node{
    string elem;
    struct node* next;
    struct node* pre;
}Node;

Node* newNode(Node* head, string data){
    Node* p = new Node();
    p->elem.assign(data);
    p->next = head->next;
    p->pre = NULL;
    return p;
}

Node* createLinkedlist(Node* head){
    Node* p = head;
    while(1){
        string tmp;
        cin>>tmp;
        if(!tmp.compare("-1"))
            return head;
        Node* pp = newNode(head, tmp);
        p->next = pp;
        pp->pre = p;
        head->next->pre = pp;
        p = p->next;
    }
    return head;
}

Node* deleteNode(Node* head, string s){
    Node* p = head->next;
    Node* pp = p;
    int flag = 0;
    int state;
    do{
        state = 0;
        if(!pp->elem.compare(s)){
            Node* tmp = pp;
            pp = pp->next;
            tmp->next->pre = tmp->pre;
            tmp->pre->next = tmp->next;
            free(tmp);
            if(head->next == tmp){
                head->next = pp;
                p = pp;
                state = 1;
            }
            flag = 1;
        }
        else
            pp = pp->next;
    }while(pp != p || state);

    if(!flag)
        cout<<-1<<endl;

    return head;
}

void myPrint(Node* head){
    Node* p = head->next;
    cout<<p->elem<<" ";
    Node* pp = p->next;
    while(pp != p){
        cout<<pp->elem<<" ";
        pp = pp->next;
    }
    cout<<endl;
}

int main(){
    Node* head = new Node();
    head->next = head;
    head->elem = "";
    head->pre = head;
    head = createLinkedlist(head);
    while(1){
        string tmp;
        cin>>tmp;
        if(!tmp.compare("-1"))
            break;
        head = deleteNode(head, tmp);
    }
    myPrint(head);
    return 0;
}

1008. 线性表去重

https://acm.ecnu.edu.cn/contest/447/problem/1008/

题解

先排个序。然后将数组左侧一块区域当作去重后的数组,标记最右侧的指针为newlen,初值为1,因为第一个元素肯定是要的。然后从i=1开始遍历到末尾,如果碰到和前面一个不一样的元素,就把它塞到左侧区域的最右端,然后newlen+1。
这样做的好处是:

  • 节约了空间。只需要开一个数组即可。
  • 节约了时间。如果一个一个删过去,复杂度很高。这里的复杂度只有O(nlogn)的排序时间,删除操作是线性时间。

代码

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

int dedup(int *a, int n){
    int newlen = 1;
    for(int i = 1; i < n; i++){
        if(a[i] != a[i-1])
            a[newlen++] = a[i];
    }
    return newlen;
}

bool cmp(int a, int b){
    return a<b;
}

int main(){
    int n;
    cin>>n;
    int a[10001] = {0};
    for(int i = 0; i < n; i++)
        cin>>a[i];
    sort(a, a+n, cmp);
    int len = dedup(a, n);
    sort(a, a+len, cmp);
    for(int i = 0; i < len; i++)
        cout<<a[i]<<" ";
    cout<<endl;
    return 0;
}

1009. 线性表顺序查找

https://acm.ecnu.edu.cn/contest/447/problem/1009/

题解

不会直接/remake

代码

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

int main(){
    int n;
    cin>>n;
    int a[100001] = {0};
    for(int i = 0; i < n; i++)
        cin>>a[i];
    int v;
    cin>>v;
    for(int i = 0; i < n; i++){
        if(a[i]==v){
            cout<<i<<endl;
            return 0;
        }
    }
    cout<<-1<<endl;
    return 0;
}

1010. 线性表二分查找

https://acm.ecnu.edu.cn/contest/447/problem/1010/

题解

不会有人不会吧

代码

#include <stdio.h>

int binarySearch(int *a, int n, int x){
    int mid;
    int left = 0;
    int right = n-1;
    while(left<=right){
        if ((right + left) % 2 != 0)
            mid = (right + left) / 2 + 1;
        else
            mid = (right + left) / 2;
        if (a[mid] == x) return mid;
        else if(a[mid] > x) right = mid-1;
        else left = mid+1;
    }
    return -1;
}

#define N 1000001
int a[N];
int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
        scanf("%d", &a[i]);
    int x;
    scanf("%d", &x);
    printf("%d\n", binarySearch(a, n, x));
    return 0;
}

1011. 经典的猜数游戏

https://acm.ecnu.edu.cn/contest/447/problem/1011/

题解

二分查找增强版,自己设立left、right和mid然后二分法。注意正负奇数除以二的取整。

代码

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

int main(){
    int mid = 0;
    int left = -1e9;
    int right = 1e9;
    string ans;
    while(ans.compare("equal")){
        cout<<mid<<endl;
        cin>>ans;
        if(!ans.compare("equal"))
            break;
        if(!ans.compare("big"))
            right = mid-1;
        if(!ans.compare("small"))
            left = mid+1;
        if ((right+left)%2 != 0){
            if(right+left < 0)
                mid = (left+right)/2-1;
            else
                mid = (left+right)/2+1;
        }
        else
            mid = (left+right)/2;
    }
    return 0;
}

1012. 环形队列

https://acm.ecnu.edu.cn/contest/447/problem/1012/

题解

建议使用不带标记的环形队列结构来节省时间。但需要额外的一个内存。因此记得将MAXN设为100002。

代码

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

int a[MAXN] = {0};

int fr = 0, re = 0;

void enqueue(int x){
    re = (re+1)%MAXN;
    if(fr == re){
        if(!re)
            re = MAXN-1;
        else
            re--;
        cout<<"Full"<<endl;
        return;
    }
    a[re] = x;
    return;
}

void dequeue(){
    if(fr == re){
        cout<<-1<<endl;
        return;
    }
    fr = (fr+1)%MAXN;
    cout<<a[fr]<<endl;
    return;
}

int main(){
    int n;
    cin>>n;
    for(int i = 0; i < n; i++){
        string s;
        cin>>s;
        if(!s.compare("dequeue"))
            dequeue();
        else{
            int x;
            cin>>x;
            enqueue(x);
        }
    }
    return 0;
}

1013. 医疗调度系统

https://acm.ecnu.edu.cn/contest/447/problem/1013/

题解

看清楚指令只有1000个就很好写了。假设有1000个N指令,那么数字最大也就1000。所以只需要开到千位的数组就能做了,不是很难的队列模拟题。

代码

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

int main() {
    char cmd;
    int people = 0, no = 0, elem = 0, ansno = 0;
    int casek = 1;
    while (cin >> people >> no) {
        int Queue[3000] = {0};
        int front = 0, rear = 0;
        int counter = 0;
        if (people == 0 && no == 0) {
            break;
        }
        cout <<"Case "<< casek <<":"<< endl;

        for (int i = 0; i < min(people, no); i++) {
            Queue[1000 + i] = i + 1;
            rear = 1001 + i;
        }
        front = 1000;
        for (int i = 0; i < no; i++) {
            cin >> cmd;
            if (cmd == 'N') {
                while (Queue[front] == 0) 
                    front++;
                cout << Queue[front] << endl;
                Queue[rear++] = Queue[front];
                Queue[front++] = 0;
            } 
            else if (cmd == 'E') {
                cin >> elem;
                for (int j = front; j < rear; j++) {
                    if (Queue[j] == elem)
                        Queue[j] = 0;
                }
                Queue[--front] = elem;
            }
        }
        casek++;
    }
}

1014. 循环打印

https://acm.ecnu.edu.cn/contest/447/problem/1014/

题解

循环链表即可。注意这题步长和初始值有点怪,调一下就行了。

代码

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

typedef struct LinkedList{
    int elem;
    struct LinkedList* next;
    int num;
}node;

node* newNode(int elem){
    node* p = (node*)malloc(sizeof(node));
    p->elem = elem;
    p->next = NULL;
    return p;
}

node* createLinkedList(int n){
    node* head = newNode(0);
    node* p = head;
    for(int i = 1; i <= n; i++){
        node* tmp = newNode(i);
        p->next = tmp;
        p = p->next;
    }
    p->next = head->next;
    head->num = n;
    return head;
}

node* deleteNode(node* p){
    node* tmp = p;
    p = p->next;
    cout<<p->elem<<" ";
    tmp->next = p->next;
    free(p);
    return tmp;
}

int main(){
    int n, i, k;
    cin>>n>>i>>k;
    node* head = createLinkedList(n);
    node* p = head;
    for(int j = 1; j < i; j++)
        p = p->next;
    while(head->num){
        for(int j = 0; j < k-1; j++)
            p = p->next;
        p = deleteNode(p);
        head->num--;
    }
    return 0;
}

1015. 查词典

https://acm.ecnu.edu.cn/contest/447/problem/1015/

题解

队列简单题。只要完成最基本的入队和出队操作就行了。查询可以用hashmap,也可以直接遍历查找,因为输入数据的规模比较小,所以不会慢多少。(我还以为是离线缓存,解决这个问题可以搜一下最远将来算法,但这题显然更简单)。

代码

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

string cache[20001];
int front = 0, rear = -1;
map<string, bool> tb;

int main(){
    int m, n;
    cin>>m>>n;
    int cnt = 0;
    for(int i = 0; i < n; i++){
        string s;
        cin>>s;
        if(!tb.count(s)){
            if(rear-front >= m-1)
                tb.erase(cache[front++]);
            rear++;
            cache[rear] = s;
            tb.insert(make_pair(s, true));
            cnt++;
        }
    }
    cout<<cnt<<endl;
    return 0;
}

1016. 欣赏书法

https://acm.ecnu.edu.cn/contest/447/problem/1016/

题解

滑动窗口法。也可以把滑动窗口看成一个队列。差不多一个意思。
记录一个res值,r先向右移动到res=m为止。再移动l,保证res=m的情况下,移动到能移动到的最右端。记录目前的l,r,size。再移动一次l,移动r到res=m为止。终止条件为l < n-m

代码

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

int a[1000005] = {0};
int tb[5009] = {0};

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    int res = 0, rl = 1, rr = 0, size = 50001, nowsize = rr - rl + 1, l = 1, r = 0;
    while (l < n - m) {
        while (res < m && r < n) {
            if (!tb[a[++r]])
                res++;
            tb[a[r]]++;
            nowsize++;
        }
        while (res == m) {
            if (nowsize < size) {
                size = nowsize;
                rl = l;
                rr = r;
            }
            tb[a[l]]--;
            nowsize--;
            if (!tb[a[l++]])
                res--;
        }
        if (res < m && r >= n)
            break;
    }
    if (!rr)
        rr++;
    cout << rl << " " << rr << endl;
    return 0;
}

1022. 波兰表达式

https://acm.ecnu.edu.cn/contest/447/problem/1022/

题解

经典栈操作。一个比较骚的操作是,可以用函数调用的顺序也是依据栈的顺序这个特点来简化代码。

代码

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

double solve(){
    char s[10086];
    cin >> s;
    switch(s[0])
    {
    case '+':
        return solve() + solve();
        break;
    case '-':
        return solve() - solve();
        break;
    case '*':
        return solve() * solve();
        break;
    case '/':
        return solve() / solve();
        break;
    default:
        return atof(s);
        break;
    }
}

int main(){
    printf("%.6lf\n", solve());
    return 0;
}

1023. 一元多项式乘法

https://acm.ecnu.edu.cn/contest/447/problem/1023/

题解

这是我很久以前写的代码了,比较繁琐。看个乐呵就行。这题大一学过,不谈。

代码

#include <stdio.h>
#include <string.h>
int main(void)
{
    char s1[120], s2[120];
    while((scanf("%s %s",s1,s2))!=EOF)
    {
        int time[101]={0}, n1[51]={0}, n2[51]={0}, i, coe, exp, pro, sig;//coe:系数,exp:次数,pro:进程,sig:符号
        int m=strlen(s1), n=strlen(s2);
        //读第一个多项式
        for(i=0, coe=0, exp=1, pro=0, sig=1; i<m; i++)
        {
            if(s1[i]=='x'&&pro!=0) {n1[0]=0; n1[1]=coe; pro=1;}//进程1,计算x的次数
            else if(s1[i]=='x'&&pro==0)
            {
                if(s1[i+1]=='^') {coe=1*sig; pro=1;}
                else {coe=1*sig; n1[1]=coe; pro=1;}
            }
            else if(s1[i]=='^') continue; 
            else if(pro!=1&&s1[i]=='+') {sig=1;}//加法
            else if(pro==1&&s1[i]=='+') {pro=0;sig=1;}
            else if(pro!=1&&s1[i]=='-') {sig=-1;}//减法
            else if(pro==1&&s1[i]=='-') {pro=0;sig=-1;}
            else if(pro==1)
            {
                exp=0;
                while(s1[i]>='0'&&s1[i]<='9')
                {
                    exp+=s1[i]-'0';
                    if(s1[i+1]>='0'&&s1[i+1]<='9'){exp*=10;i++;}
                    else break;
                }
                n1[exp]=coe;
                n1[1]=0;
                n1[0]=0;
            }
            else if(pro==0)//进程0,计算x的系数
            {
                coe=0;
                while(s1[i]>='0'&&s1[i]<='9')
                {
                    coe+=s1[i]-'0';
                    if(s1[i+1]>='0'&&s1[i+1]<='9'){coe*=10;i++;}
                    else break;
                }
                coe*=sig;
                n1[0]=coe;//暂时存储到0次项
                pro=2;//进程2,读取x
            }
        }
        //以下读第二个多项式
        for(i=0, coe=0, exp=1, pro=0, sig=1; i<n; i++)
        {
            if(s2[i]=='x'&&pro!=0) {n2[0]=0; n2[1]=coe; pro=1;}//进程1,计算x的次数
            else if(s2[i]=='x'&&pro==0)
            {
                if(s2[i+1]=='^') {coe=1*sig; pro=1;}
                else {coe=1*sig; n2[1]=coe; pro=1;}
            }
            else if(s2[i]=='^') continue;
            else if(pro!=1&&s2[i]=='+') {sig=1;}//加法
            else if(pro==1&&s2[i]=='+') {pro=0;sig=1;}
            else if(pro!=1&&s2[i]=='-') {sig=-1;}//减法
            else if(pro==1&&s2[i]=='-') {pro=0;sig=-1;}
            else if(pro==1)
            {
                exp=0;
                while(s2[i]>='0'&&s2[i]<='9')
                {
                    exp+=s2[i]-'0';
                    if(s2[i+1]>='0'&&s2[i+1]<='9'){exp*=10;i++;}
                    else break;
                }
                n2[exp]=coe;
                n2[1]=0;
                n2[0]=0;
            }
            else if(pro==0)//进程0,计算x的系数
            {
                coe=0;
                while(s2[i]>='0'&&s2[i]<='9')
                {
                    coe+=s2[i]-'0';
                    if(s2[i+1]>='0'&&s2[i+1]<='9'){coe*=10;i++;}
                    else break;
                }
                coe*=sig;
                n2[0]=coe;//暂时存储到0次项
                pro=2;//进程2,读取x
            }
        }
        //以下计算结果多项式的系数
        int j, ans[101], cnt=0;
        for(i=0; i<51; i++)
            for(j=0; j<51; j++)
                time[i+j]+=n1[i]*n2[j];
        for(i=100; i>=0; i--)
            if(time[i])
                ans[cnt++]=time[i];
        for(i=0; i<cnt-1; i++)
            printf("%d ",ans[i]);
        printf("%d\n",ans[i]);
    }
    return 0;
}

1032. 字串排序

https://acm.ecnu.edu.cn/contest/447/problem/1032/

题解

卡题的点:要用strcmp就别用sort,用qsort,两个函数cmp的返回值不一样。
其他没啥难度,抽象一个结构体,里面有字符串和包含的数字。之后开结构体数组排序输出即可。

代码

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

typedef struct str{
    char s[35];
    long long num;
}S;

int cmp(const void *A, const void *B){
    S Q = *(S*)A;
    S P = *(S*)B;
    if(Q.num ==  P.num) return strcmp(Q.s, P.s);
    else return Q.num - P.num;
}

int main(){
    S strs[105];
    for(int i = 0; i < 105; i++)
        strs[i].num = -1;
    int k = 0;
    while(scanf("%s", strs[k].s)!=EOF){
        int slen = strlen(strs[k].s);
        long long n = 0, flag = 0;
        for(int i = 0; i < slen; i++){
            if(strs[k].s[i]<='9' && strs[k].s[i]>='0'){
                n = n*10 + strs[k].s[i] - 48;
                flag = 1;
            }
        }
        if(flag)
            strs[k++].num = n;
        else
            strs[k++].num = -1;
    }
    qsort(strs, k, sizeof(S), cmp);
    for(int i = 0; i < k; i++)
        printf("%s ", strs[i].s);
    return 0;
}

1037. 字符串消除

https://acm.ecnu.edu.cn/contest/447/problem/1037/

题解

我是笨比,我只会四重循环硬算,一个个情况枚举过去。
听说有数学方法更快,反正数据规模就10^4,随便做了。
开个string类型插入更方便,vector也行吧。开数组还是太麻烦了。

代码

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

string tb[3] = {"A", "B", "C"};

int main(){
    int T;
    cin>>T;
    for(int i = 0; i < T; i++){
        string s;
        cin>>s;
        int num = 0;
        for(int j = 0; j <= s.size(); j++){
            for(int k = 0; k < 3; k++){
                string tmp = s;
                tmp.insert(j, tb[k]);
                int len = tmp.size();
                while(1){
                    int flag = 0;
                    for (string::iterator it = tmp.begin(), t, s; it < tmp.end() - 1;){
                        if (*(it + 1) == *it){
                            flag = 1;
                            int x = it - tmp.begin();
                            t = it;
                            while (it < tmp.end() - 1 && *(it + 1) == *it)
                                it++;
                            tmp.erase(t, it + 1);
                            x = x < 0 ? 0 : x;
                            it = tmp.begin() + x;
                        }
                        else
                            it++;
                    }
                        if (flag == 0)
                            break;
                }
                num = num>(len-tmp.size())?num:len-tmp.size();
            }
        }
        cout<<"case #"<<i<<":"<<endl;
        cout<<num<<endl;
    }
    return 0;
}

1038. 反转字符串

https://acm.ecnu.edu.cn/contest/447/problem/1038/

题解

不是很懂这题要干啥,我反着输出不就行了吗?

代码

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

int main(){
    char s[100001] = {'\0'};
    char ch;
    int idx = 0;
    while((ch=getchar())!=EOF){
        if(ch == '\n'){
            for(int i = idx-1; i >= 0; i--)
                cout<<s[i];
            cout<<endl;
            idx = 0;
            continue;
        }
        s[idx++] = ch;
    }
    return 0;
}

1044. GPS数据处理

https://acm.ecnu.edu.cn/contest/447/problem/1044/

题解

神烦题。阅读理解题。

代码

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

int main(){
    string s;
    cin>>s;
    stack<char> st;
    int hou, min, sec;
    while(s!="END"){
        int i = 1;
        string tmps = "$GPRMC";
        int flag = 1;
        for(; i <= 5; i++){
            if(s[i]!=tmps[i])
                flag = 0;
        }
        if(!flag){
            cin>>s;
            continue;
        }
        i = s.length()-1;
        while(s[i]!='*')
            st.push(s[i--]);
        int cor = 0;
        while(!st.empty()){
            int tmp;
            if(st.top()<='F' && st.top()>='A')
                tmp = st.top()-'A'+10;
            else
                tmp = st.top()-'0';
            cor = cor*16+tmp;
            st.pop();
        }
        int res = s[1];
        for(int j = 2; j < i; j++)
            res ^= s[j];
        res %= 65535;
        if(res != cor){
            cin>>s;
            continue;
        }
        else{
            i = 0;
            int time = 0;
            while(s[i++]!=',');
            time = i;
            while(s[i++]!=',');
            if(s[i]!='A'){
                cin>>s;
                continue;
            }
            hou = (s[time]-'0')*10+(s[time+1]-'0')+8;
            hou %= 24;
            min = (s[time+2]-'0')*10+(s[time+3]-'0');
            sec = (s[time+4]-'0')*10+(s[time+5]-'0');
            cin>>s;
        }
    }
    if(hou < 10) cout<<0;
        cout<<hou<<":";
    if(min < 10) cout<<0;
        cout<<min<<":";
    if(sec < 10) cout<<0;
        cout<<sec<<endl;
    return 0;
}

留下评论