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;
}
总结
其实模拟方法有很多,这个是最朴素的一种,一开始思路就这样想,没有优化就交了。
- 一个好的指挥官不会背叛他的军队,无论代价是什么。
- 一个更好的指挥官知道当他想背叛他的军队时,什么时候应该伪装。
- 一个最好的指挥官精明地确立自己的绝对领导,并引领着人民走向更好的未来。