CF158C Cd and pwd commands 题解

题面

大模拟,但是有坑点。

思路

依照题意模拟。用一个字符串 \(out\) 记录在进行了 \(i\) 次操作后如果要输出输出的东西,字符串 \(in\)\(s\) 来分别记录输入的操作及操作类型。

由于输出的第一个字符一定是 /,所以可以直接将 \(out\) 的初始化定为 out = "/"。这样子可以省去很多麻烦。又因为输出的最后一个字符也一定是 /,而输入的字符串 \(in\) 最后一定不带 /,所以可以直接在后面加上一个 /,像 in = in + '/' 这样。

当然,要特判绝对路径的情况,这个时候的 \(in\) 的第一个字符就是 /,没必要再加。即使是绝对路径也会有删除操作,这里需要注意!!!

遍历一遍输入的 \(in\),用一个变量 \(last\) 来记录对于当前in[i] = '/' 时的上一个 / 的位置。调用函数 check(last , i) 来操作。

传入的其实就是两个 / 的位置,每次都对这两个位置间的字符串进行操作。特判当长度为二时是否是删除操作,是的话就调用函数 del()。不是的话就将这一段加入到 \(out\) 中,调用函数 add(l , r),其中 \(l\) 为上面的 \(last\)\(r\) 为上面的 \(i\)

代码

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<stdio.h>
#define ll long long
#define inf 0x3f3f3f3f
#define fr(i , a , b) for(ll i = a ; i <= b ; ++i)
#define fo(i , a , b) for(ll i = a ; i >= b ; --i)
#pragma comment(linker , "/stack : 200000000")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
inline char gchar()
{
    static char buf[1000000] , *p1 = buf , *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 1000000 , stdin) , p1 == p2) ? EOF : *p1++;
}
inline ll read()
{
    ll x = 0 , f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
	  {
        if(ch == '-')
        {
        	f = -1;
		}
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
	  {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
ll n;
string s , in , out;
inline void del()
{
    ll len_out = out.size();
    if(len_out == 1)
    {
        return ;
    }
    ll L = 0 , R = 0;
    fo(i , len_out - 1 , 0)
    {
        if(out[i] == '/' && R == 0)
        {
            R = i;
            continue;
        }
        if(out[i] == '/' && R != 0)
        {
            L = i;
            break;
        }
    }
    // printf("del : L = %lld R =  %lld\n" , L , R);
    out.erase(L + 1 , R);//从L + 1开始就不需要加回‘/’了
    // cout << "out = " << out << endl;
}
inline void add(ll L , ll R)
{
    string kkk;
    fr(i , L + 1 , R)
    {
        kkk += in[i];
    }
    out += kkk;
    // cout << "out = " << out << endl;
}
inline void check(ll l , ll r)
{
    if(r - l - 1 == 2)
    {
        if(in[l + 1] == '.' && in[r - 1] == '.')
        {
            del();
        }
        else
        {
            add(l , r);
        }
    }
    else
    {
        add(l , r);
    }
}
signed main()
{
    n  = read();
    out = "/";
    while(n--)
    {
        cin >> s;
        if(s == "pwd")
        {
            cout << out;
            puts("");
        }
        else if(s == "cd")
        {
            cin >> in;
            in = in + '/';
            if(in[0] == '/')
            {
                out = "/";
            }
            else
            {
                in = '/' + in;
            }
            ll len = in.size() , last = 0;
            fr(i , 0 , len - 1)
            {
                if(in[i] == '/')
                {
                    // cout << in;
                    // puts("");
                    // printf("check : l = %lld r =  %lld\n" , last , i);
                    check(last , i);
                    last = i;
                }
            }
        }
    }
    system("pause");
    return 0;
}

总结

其实模拟方法有很多,这个是最朴素的一种,一开始思路就这样想,没有优化就交了。

posted @ 2024-04-10 21:36  心海秋的墨木仄  阅读(4)  评论(0编辑  收藏  举报