11月8日——离noip还有11天

今天花式GG
先放出了不明所以的三道题

A 题

这里写图片描述
问题描述:
Bob 有 n 个士兵,他们排成一列按照从左到右编号为 1 到 n,每个士兵都有自己的 IQ 值,
Bob 喜欢有序的东西,他想要让这些士兵按照 IQ 的大小从小到大排序。于是 Bob 决定进行
m 次操作,每次选一个士兵,让他开始整理部队。当士兵被选中的时候,士兵会向后的士兵
(编号大于该士兵)发出指令。但是因为 IQ 的原因,只有 IQ 低于该士兵的士兵才会听从
指令。那么这些士兵会按照 IQ 从小到大顺序重新排列在这些士兵之前的位置上,并重新编
号。那么 Bob 想知道,当他选出一些士兵之后,总体士兵 IQ 的逆序对有多少个。
输入:
第一行包含三个整数 n,m,表示士兵的个数和 Bob 操作的次数。
接下来 n 个数字,a1,a2an(ai<1e9),分别表示编号 1,2n 的士兵的 IQ 值。
输出:
输出 m+1 的整数,分别是一开始的逆序对数,进行了 i 次操作后的逆序对数。

样例输入:
3 2
2 3 1
1
1
样例输出:
2
1
1
初始的逆序对数为 2,当选中第一个数的时候,后面小于 2 的数只有 1,重排和重编号后变
为 1 3 2,逆序对数变成了 1。再次选中第一个数,后面没有小于 1 的数,所以都不会动,
逆序对数不变。注(IQ 可能有相同的士兵)

数据范围:
对于 40%的数据,1 <= n <= 20,1 <= m <= 20。
对于 70%的数据,1 <= n,m <= 10^3。
对于 100%的数据,1 <= n,m <= 10^5

好人一辈子,代码附上:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <queue>
using namespace std;
typedef long long LL;
#define For(i,a,b) for (int i = (a); i <= (b); i++)
#define Cor(i,a,b) for (int i = (a); i >= (b); i--)
#define rep(i,a) for (int i = 0; i < a; i++)
#define Fill(a,b) memset(a,b,sizeof(a))
const int maxn = 500010;
const int maxm = 1e6 + 10;
const int inf = 1e9;
struct node
{
    int v, id, p;
}P[maxn];
int n, m;
int f[maxn];
void init()
{
    scanf("%d%d", &n, &m);
    For(i, 1, n)
        scanf("%d", &P[i].v), P[i].id = i, P[i].p = f[i] = inf;
    rep(i, m)
    {
        int x;
        scanf("%d", &x);
        if (P[x].p == inf)
            P[x].p = f[x] = i;
    }
}
struct BIT
{
    int val[maxm];
    void add(int x, int v)
    {
        for (int i = x; i < maxm; i += i & (-i))
            val[i] += v;
    }
    int ask(int x)
    {
        int ret = 0;
        for (int i = x; i; i -= i & (-i))
            ret += val[i];
        return ret;
    }
}b;
int g[maxn];
LL F[maxn];
int mn[maxn<<2];
void up(int id,int l,int r,int v,int w)
{
    if(l==r){
        mn[id]=min(mn[id],w);return;
    }
    int mid=(l+r)>>1;
    if(v<=mid) up(id<<1,l,mid,v,w);
    else up(id<<1|1,mid+1,r,v,w);
    mn[id]=min(mn[id<<1],mn[id<<1|1]);
}
int q(int id,int l,int r,int tl,int tr)
{
    if(tl==l&&r==tr) return mn[id];
    int mid=(l+r)>>1;
    if(tr<=mid) return q(id<<1,l,mid,tl,tr);
    else if(tl>mid) return q(id<<1|1,mid+1,r,tl,tr);
    else return min(q(id<<1,l,mid,tl,mid),q(id<<1|1,mid+1,r,mid+1,tr));
}
int a[maxn];
map<int,int> mp;
void solve()
{
    LL ans = 0;
    Cor(i, n, 1)
    {
        g[i] = b.ask(P[i].v);
        b.add(P[i].v + 1, 1);
        ans += g[i];
        a[i]=P[i].v;
    }
    sort(a+1,a+1+n);
    int cnt=1;
    for(int i=1;i<=n;i++)
    {
        if(mp[a[i]]) continue;
        mp[a[i]]=cnt++;
    }
    printf("%lld\n", ans);
    memset(mn,127,sizeof(mn));
    for(int i=1;i<=n;i++)
    {
        P[i].v=mp[P[i].v];
        up(1,1,cnt,P[i].v,P[i].p);
        int t=q(1,1,cnt,P[i].v,cnt);
        if(t>m) continue;
        F[t]+=g[i];
    }
    rep(i, m)
    {
        ans -= F[i];
        printf("%lld\n", ans);
    }
}
int main()
{
    init();
    solve();
    return 0;
}

B 题

这里写图片描述
问题描述:
四个机器人,在 3 * 3 的方格里,一开始四个机器人分别站在 9 个格子上,每一步机器人可
以往临近的一个格子移动或留在原地(同一个格子可以有多个机器人停留),经过 n 步后有
多少种不同的走法,使得每个毯子上都有 1 机器人停留。由于方法数量巨大,输出 Mod
10^9 + 7 的结果。
输入:
第一行包含一个整数 n。
输出:

输出一行输出走法的数量 Mod 10^9 + 7
样例输入:
1

样例输出:
229

数据范围:
对于 40%的数据,1 <= n<= 10;
对于 70%的数据,1 <= n <= 10^6;
对于 100%的数据,1 <= n <= 10^18。

这道题的代码也附上:

#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;

struct Matrix
{
    long long a[9][9];
}ma;
Matrix mull(Matrix a,Matrix b)
{
    Matrix ans;
    for(int i=0;i<9;i++)
    {
        for(int j=0;j<9;j++)
        {
            ans.a[i][j]=0;
            for(int k=0;k<9;k++)
                ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
        }
    }
    return ans;
}
Matrix fast(long long ci,Matrix num)
{
    Matrix ans;
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++)
        ans.a[i][j]=(i==j);
    while(ci){
        if(ci&1) ans=mull(ans,num);
        num=mull(num,num);ci=ci>>1;
    }
    return ans;
}
int a[10];
int main()
{
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++)
            ma.a[i][j]=((abs(i%3-j%3)+abs(i/3-j/3))==1);
    for(int i=0;i<9;i++)
        ma.a[i][i]=1;
    long long n;
    scanf("%lld",&n);
    ma=fast(n,ma);
    for(int i=0;i<9;i++)
        a[i]=i;
    long long ans=0;
    for(int i=0;i<362880;i++)
    {
        long long tmp=1;
        for(int j=0;j<9;j++)
        {
            tmp=tmp*ma.a[j][a[j]]%mod;
        }
        ans=(ans+tmp)%mod;
        next_permutation(a,a+9);
    }
    printf("%lld\n",ans);
    return 0;
}

C 题

这里写图片描述
这里写图片描述
千星大大快更新!!!
问题描述:
计算 gcd(i,j)的 k 次方的和,其中 1<=i<=n,1<=j<=n;
输入:
第一行包含两个整数 n,k。

输出:
输出一行,表示对应的答案。

样例输入:
2 2

样例输出:
7

数据范围:
对于 40%的数据,1 <= n <= 10^3;
对于 70%的数据,1 <= n <= 10^6;
对于 100%的数据,1 <= n <= 10^10,
对于所有的数据 1<=k<=5

GG

#include <bits/stdc++.h>
using namespace std;
const int maxn=5000005;
const int mod=1e9+7;
int pri[maxn],fi[maxn],t;
bool flag[maxn];
long long sumfi[maxn];
long long mod2,mod3,mod6,mod12,mod30;
long long fast(long long num,int ci)
{
    long long ans=1;
    while(ci)
    {
        if(ci&1) ans=ans*num%mod;
        num=num*num%mod;ci=ci>>1;
    }
    return ans;
}
map<long long ,long long>mp;
void pre()
{
    t=0;memset(flag,0,sizeof(flag));
    fi[1]=1;
    for(int i=2;i<maxn;i++)
    {
        if(!flag[i]){
            pri[t++]=i;fi[i]=i-1;
        }
        for(int j=0;j<t&&pri[j]*i<maxn;j++)
        {
            flag[pri[j]*i]=1;
            if(i%pri[j]==0){
                fi[i*pri[j]]=fi[i]*pri[j];
                break;
            }
            fi[i*pri[j]]=fi[i]*(pri[j]-1);
        }
    }
    for(int i=1;i<maxn;i++)
    {
        sumfi[i]=sumfi[i-1]+fi[i];
        if(sumfi[i]>=mod) sumfi[i]-=mod;
    }
    mod2=fast(2,mod-2);
    mod3=fast(3,mod-2);
    mod6=fast(6,mod-2);
    mod12=fast(12,mod-2);
    mod30=fast(30,mod-2);
    mp.clear();
}

long long gett(long long n,int k)
{
    n%=mod;
    if(k==1)
        return n*(n+1)/2%mod;
    if(k==2)
        return n*(n+1)%mod*(2*n+1)%mod*mod6%mod;
    if(k==3){
        long long t=n*(n+1)/2%mod;;
        return t*t%mod;
    }
    if(k==4){
        return n*(n+1)%mod*(2*n+1)%mod*((3*n*n%mod+3*n-1)%mod)%mod*mod30%mod;
    }
    if(k==5){
        long long t=n*(n+1)%mod;
        t=t*t%mod;
        t=t*((2*n*n%mod+2*n-1)%mod)%mod;
        t=t*mod12%mod;
        return t;
    }
}
long long solve(long long u)
{
    if(u<maxn){
        return sumfi[u];
    }
    if(mp[u]) return mp[u];
    long long tmp=u%mod;
    long long ans=tmp*(tmp+1)/2%mod;
    for(long long i=2,j;i<=u;i=j+1)
    {
        j=u/(u/i);
        ans=(ans-solve(u/i)*(j-i+1))%mod;
    }
    ans%=mod;
    if(ans<0) ans+=mod;
    mp[u]=ans;
    return ans;
}

int main()
{
    pre();
    long long n;
    int k;
    scanf("%lld%d",&n,&k);
    long long ans=0;
    for(long long i=1,j;i<=n;i=j+1)
    {
        j=n/(n/i);
        ans=(ans+solve(n/i)*(gett(j,k)-gett(i-1,k)))%mod;
    }
    ans=ans*2;
    ans=ans-gett(n,k);
    ans%=mod;
    if(ans<0) ans+=mod;
    printf("%lld\n",ans);
    return 0;
}

只能呵呵,
算了还是给份题解吧!

题解

A

我们考虑计算一个数之后有多少比他小的数来计算整体的逆序对数。可以发现的是,当我们对一个数字进行操作是,所有比他的数对逆序对的贡献是不变,比他小且在他后面的逆序对数的贡献要变成0。所以对于一个数来说,他的贡献变为0的时刻就是在他前面比他大的而且最早进行的操作对应的时刻。这样的话我们就可以用线段树来维护了,当然也可以分治来做,复杂度O(nlogn)

B

一共只有9个格子,我们对它进行编号,可以构成一个9×9的转移矩阵,进行快速幂之后9!的枚举每个棋子最终的位置即可。复杂度O(9^3×logk+9!);

C

……….
这里写图片描述

然后就没有然后了;//直接GG

智乃

——一来就看见了这张图
(出题者真宅男)
这里写图片描述
【题目描述】

给你N个字符串,你每次可以选择其中一个字符串的一段前缀进行翻转,但
是你必须保证这个前缀的长度是偶数。你可以进行无限次这样的操作,并且如果
两个字符串变得相同的时候,你就可以把这两个字符串都删除掉,问最后最少剩
下多少个字符串?

【输入格式】

第一行一个整数T代表数据组数。
对于每组数据,第一行一个整数N代表字符串个数。
接下来N行每行一个字符串。

【输出格式】

对于每组数据,一行一个整数代表答案。

【样例输入】
2
5
esprit
god
redotopc
odcpoter
dog
14
rats
live
stressed
to
act
as
star
desserts
of
evil
cat
sa
fo
ot
【样例输出】
3
0

【样例解释】

无。 (那你写来干嘛)

【数据范围与规定】

对于40%的数据,字符串长度不超过8。
对于100%的数据,1 <=T<=11,字符串长度不超过50,1<=T<=50。

题解

其实我认为暴搜应该可以过
毕竟数据很水吗~~~~
所以可以枚举奇数位和偶数位的转换情况,找长度相同的字符串依次比较,O(10^7)左右后就可以出答案了;

code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
typedef long long LL;
template <class T> inline void read(T &x)
{
    x = 0;
    T flag = 1;
    char ch = (char)getchar();
    while(ch<'0' || ch>'9')
    {
        if(ch == '-') flag = -1;
        ch = (char)getchar();
    }
    while(ch>='0' && ch<='9')
    {
        x = (x<<1) + (x<<3) + ch - '0';
        ch = (char)getchar();
    }
    x *= flag;
}
template <class T> T gcd(T a,T b) { return !b?a:gcd(b,a%b); }
const int INF=0x3f3f3f3f;
const int maxn = 55;
string s;
int n;
map <string,int> mp;
inline void init()
{
    mp.clear();
    read(n);
    for(int k=1;k<=n;k++)
    {
        cin>>s;
        int lens = s.size();
        for(int i=0;(i|1)<lens;i+=2) if(s[i]>s[i|1]) swap(s[i],s[i|1]);
        for(int i=0;(i|1)<lens;i+=2)
            for(int j=0;(j|1)<lens-(i+2);j+=2)
                if(s.substr(j,2)>s.substr(j+2,2))
                    swap(s[j],s[j+2]),swap(s[j|1],s[(j|1)+2]);
        if(mp.count(s)) mp[s]++;
        else mp[s]=1;
    }
}
int work()
{
    int ans = 0;
    for(map <string,int> ::iterator it = mp.begin(); it!=mp.end(); it++)
        ans += it->second % 2;
    return ans;
}
int main()
{
    freopen("kahuucino.in","r",stdin);
    freopen("kahuucino.out","w",stdout);
    int T;
    read(T);
    while(T--)
    {
        init();
        int ans = work();
        printf("%d",ans);
        putchar('\n');
    }
    return 0;
}

麻耶

说好的图片
【问题描述】

油库里是幻想乡特有的一种生物。每只油库里都有一个战斗力值和一个能量
值。当两只油库里战斗时,总是战斗力值高的一位获胜。获胜者的战斗力值将变
成 (自己的原战斗力值-对手的战斗力值+对手的能量值)。败者将死去。若两者战
斗力值一样,则同归于尽。
思考熊发现了很多油库里,他想知道通过互相战斗之后油库里中战斗力值+
能量值最高的一个可能到达多少。你能帮他们求出来吗?(假设除了考察的那只
油库里之外,其他油库里之间不会发生战斗)

【输入格式】

第一行是一个整数N,代表当前有多少油库里。
接下来的N行,每一行有两个整数u, v,代表这只油库里的战斗力值和能量值。

【输出格式】

输出一个整数,代表油库里中战斗力值+能量值最高的一个能达到多少。

【样例输入】
2
1 2
2 1
【样例输出】
4
【样例解释】
无。

对于100%的数据,1 <=u,v<=10^9。

数据点编号N=数据点编号N=
12614989
2984721726
361688100000
4104709100000
51916810100000

不说别的,题解贪心

code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
typedef long long LL;
template <class T> inline void read(T &x)
{
    x = 0;
    T flag = 1;
    char ch = (char)getchar();
    while(ch<'0' || ch>'9')
    {
        if(ch == '-') flag = -1;
        ch = (char)getchar();
    }
    while(ch>='0' && ch<='9')
    {
        x = (x<<1) + (x<<3) + ch - '0';
        ch = (char)getchar();
    }
    x *= flag;
}
template <class T> T gcd(T a,T b) { return !b?a:gcd(b,a%b); }
const LL INF = (1LL<<60);
const int maxn = 100005;
struct Node
{
    LL x,y;
    Node() {}
    Node (const LL &_x,const LL &_y) { x=_x; y=_y; }
    bool operator < (const Node &t) const
    {
        if(x ^ t.x) return x < t.x;
        return y < t.y;
    }
}good[maxn],bad[maxn];
int goodn,badn;
int n;
LL sum[maxn],MAX[maxn]; // formed as prefix
inline void init()
{
    read(n);
    for(int i=1;i<=n;i++)
    {
        LL x,y;
        read(x); read(y);
        if(x < y) good[++goodn] = Node(x,y);
        else bad[++badn] = Node(x,y);
    }
    sort(good+1,good+goodn+1);
    MAX[0]=0; sum[0]=0;
    for(int i=1;i<=goodn;i++)
    {
        sum[i] = sum[i-1] + good[i].y - good[i].x;
        MAX[i] = max(MAX[i-1],good[i].x - sum[i-1]);
    }
}
inline int search(int L,int R,LL x)
{
    while(L < R)
    {
        int mid = (L+R+1)>>1;
        if(MAX[mid] < x) L = mid;
        else R = mid - 1;
    }
    return L;
}
LL work()
{
    LL ans = 0;
    smax(ans,sum[search(0,goodn-1,good[goodn].x)]+good[goodn].x+good[goodn].y);
    for(int i=1;i<=badn;i++)
    {
        int pos = search(0,goodn,bad[i].x);
        smax(ans,sum[pos]+bad[i].x+bad[i].y);
    }
    return ans;
}
int main()
{
    freopen("zyougamaya.in","r",stdin);
    freopen("zyougamaya.out","w",stdout);
    init();
    LL ans = work();
    printf(AUTO,ans);
    return 0;
}

这里写图片描述
【问题描述】

现在你要实现一个文件系统,支持以下操作

cd Directory_Name
如果当前路径下有名为 Directory_Name 的文件夹,则进入该文件夹所对应
的路径,否则输出”No such directory!”。

cd ..
如果当前路径存在父路径,则返回父路径,否则输出”No parentdirectory!”。

touch File_Name
如果当前目录下存在名为 File_Name 的文件则输出”File already exists!”,
否则创建这样一个文件。

rm File_Name
如果当前目录下存在名为 File_Name 的文件则删除它,否则输出”No such
file!”。

mkdir Directory_Name
如果在当前路径下存在名为 Directory_Name 的文件夹,则输出”Directory
already exists!” ,否则创建这样一个文件夹(当前路径不变)。

rmdir Directory_Name
如果在当前路径下存在名为 Directory_Name 的文件夹,则删除之,否则输
出”No such directory!”。

ls
列出当前路径下所有的文件和文件夹,每一项占一行,按创建的先后顺序给
出。采用以下形式输:
“Item_Name Type”
Type 为< D >(文件夹)或< F >(文件) 注:没有空格
注意:同一路径下文件与文件夹可以同名,但同一路径下文件与文件、文件
夹与文件夹不能同名。
初始时当前路径处于根路径下,无父路径。

【输出格式】
输出答案。
【样例输入】
3
mkdir standy
touch totalfrank
ls

【样例输出】
standy < D >
totalfrank < F >
【数据规模与约定】
对于100%的数据,1 <=Q<=100,所有文件名字长度不超过200且均为小写字母。

博主正在用c++与vb在windows上真实实现此代码。

一开始用map,结果虽然写得很美观

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
using namespace std;
struct NAME{
    string njsz;
    int od;
    bool operator < (const NAME rhs)const{
        return njsz<rhs.njsz;
    }
};
struct Document{        //文件夹 
    vector<int> son;    //保存当前文件夹里面的子目录地址。
    int father;         //保存当前文件夹父目录的地址。 
    NAME name;          //当前文件夹的名字。 
    bool flag;          //flag =1 表示为 文件 否则表示为文件夹 
}document[1001];
map<NAME,int> systems;
map<NAME,int>::iterator iter; 
int cnt,Q,now_data;
NAME a,b;
void Build_Document(int &now_data,int father,NAME& name){//创建文件夹 
    iter = systems.find(name);
    if((iter != systems.end())&&document[iter->second].father==now_data&&document[iter->second].flag==0)
        cout<<"Directory already exists!"<<endl;
    else{
            document[father].son.push_back(++cnt);
            document[cnt].father=father;
            document[cnt].name=name;
            document[cnt].flag=0;
            systems.insert(pair<NAME, int>(name,cnt));
        }

} 
void Build_File(int &now_data,int father,NAME& name){//创建文件 
    iter = systems.find(name);
    if((iter != systems.end())&&document[iter->second].father==now_data&&document[iter->second].flag==1) 
        cout<<"File already exists!"<<endl;
    else{
            document[father].son.push_back(++cnt);
            document[cnt].father=father;
            document[cnt].name=name;
            document[cnt].flag=1;
            systems.insert(pair<NAME, int>(name,cnt));
        }

} 
void Enter_son_index(int &now_data,NAME& name){  //进入子目录 
    iter = systems.find(name);
    if(iter != systems.end())
        now_data=iter->second;
    else 
        cout<<"No such directory!"<<endl; 
}
void Enter_file_index(int &now_data){//进入父目录
    if(document[now_data].father!=0)
        now_data=document[now_data].father;
    else
        cout<<"No parent directory!"<<endl; 
}   
void Delete_File(int &now_data,NAME& name){
    iter = systems.find(name);
    if(iter != systems.end()&&(document[iter->second].father=now_data)&&document[iter->second].flag==1){
        systems.erase(name);
    }
    else
        cout<<"No such File!"<<endl; 
}
void Delete_Document(int &now_data ,NAME& name){
    iter = systems.find(name);
    if(iter != systems.end()&&(document[iter->second].father=now_data)&&document[iter->second].flag==0){
        systems.erase(name);
    }
    else
        cout<<"No such directory!"<<endl; 
}
void Print(int &now_data){
    for (int i=0;i<document[now_data].son.size();i++){
        int v=document[now_data].son[i];
        NAME name=document[v].name;
        iter = systems.find(name);
        if(iter != systems.end()){
            if(document[v].flag==0) cout<<name.njsz<<" <D>"<<endl; 
            else cout<<name.njsz<<" <F>"<<endl;
        } 
    }
}

int main(){
    freopen("nacumegu.in","r",stdin);
    //freopen("nacumegu.out","w",stdout); 
    cin>>Q;
    now_data=0;
    while(Q--){
        cin>>a.njsz>>b.njsz;
        b.od=a.od=cnt;
        if(a.njsz=="cd"&&b.njsz!="..") 
            Enter_son_index(now_data,b);
        if(a.njsz=="cd"&&b.njsz=="..")  
            Enter_file_index(now_data);
        if(a.njsz=="touch")
            Build_File(now_data,now_data,b);  
        if(a.njsz=="rm")    
            Delete_File(now_data,b);
        if(a.njsz=="mkdir") 
            Build_Document(now_data,now_data,b);
        if(a.njsz=="rmdir") 
            Delete_Document(now_data,b);
        if(a.njsz=="ls") 
            Print(now_data);
    }
    return 0;
}

然而是error的
所以还是写人话

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<cctype>
#include<windows.h>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
typedef long long LL;
template <class T> inline void read(T &x){
    x = 0;
    T flag = 1;
    char ch = (char)getchar();
    while(ch<'0' || ch>'9')
    {
        if(ch == '-') flag = -1;
        ch = (char)getchar();
    }
    while(ch>='0' && ch<='9')
    {
        x = (x<<1) + (x<<3) + ch - '0';
        ch = (char)getchar();
    }
    x *= flag;
}
template <class T> T gcd(T a,T b) { return !b?a:gcd(b,a%b); }
const int INF=0x3f3f3f3f;
const int maxn = 120;
struct Node{
    int fa;
    string s;
    int val; // 1 for D , 2 for F
    bool disabled;
}node[maxn];
#define fa(x) node[x].fa
#define s(x) node[x].s
#define val(x) node[x].val
#define disabled(x) node[x].disabled
struct Edge{
    int to,next;
}edge[maxn];
int head[maxn];
int maxnode,maxedge;
inline void addedge(int u,int v){
    edge[++maxedge] = (Edge) { v,head[u] };
    head[u] = maxedge;
}
int root;
void initialize(){
    root = maxnode = 1;
    memset(head,-1,sizeof(head)); maxedge=-1;
}
void go_back(){
    if(!fa(root)) puts("No parent directory!");
    else root = fa(root);
}
void go_forward(const string &to){
    for(int i=head[root];~i;i=edge[i].next){
        int v = edge[i].to;
        if(disabled(v) || val(v)!=1) continue;
        if(s(v) == to){
            root = v;
            return;
        }
    }
    puts("No such directory!");
}
void touch(const string &to)
{
    for(int i=head[root];~i;i=edge[i].next)
    {
        int v = edge[i].to;
        if(disabled(v) || val(v)!=2) continue;
        if(s(v) == to)
        {
            puts("File already exists!");
            return;
        }
    }
    ++maxnode;
    fa(maxnode) = root;
    val(maxnode) = 2; // File
    s(maxnode) = to;
    addedge(root,maxnode);
}
void rm(const string &to)
{
    for(int i=head[root];~i;i=edge[i].next)
    {
        int v = edge[i].to;
        if(disabled(v) || val(v)!=2) continue;
        if(s(v) == to)
        {
            disabled(v) = true;
            return;
        }
    }
    puts("No such file!");
}
void mkdir(const string &to)
{
    for(int i=head[root];~i;i=edge[i].next)
    {
        int v = edge[i].to;
        if(disabled(v) || val(v)!=1) continue;
        if(s(v) == to)
        {
            puts("Directory already exists!");
            return;
        }
    }
    ++maxnode;
    fa(maxnode) = root;
    val(maxnode) = 1; // Directory
    s(maxnode) = to;
    addedge(root,maxnode);
}
void rmdir(const string &to)
{
    for(int i=head[root];~i;i=edge[i].next)
    {
        int v = edge[i].to;
        if(disabled(v) || val(v)!=1) continue;
        if(s(v) == to)
        {
            disabled(v) = true;
            return;
        }
    }
    puts("No such directory!");
}
stack <int> sta;
void ls()
{
    for(int i=head[root];~i;i=edge[i].next)
    {
        int v = edge[i].to;
        if(disabled(v)) continue;
        sta.push(v);
    }
    while(!sta.empty())
    {
        int u = sta.top(); sta.pop();
        cout<<s(u);
        printf(" <%c>\n",val(u)==1?'D':'F');
    }
}
int main()
{
    freopen("nacumegu.in","r",stdin);
    freopen("nacumegu.out","w",stdout);
    initialize();
    int Q;
    read(Q);
    while(Q--)
    {
        string cmd,s;
        cin>>cmd;
        if(cmd!="ls") cin>>s;
        if(cmd=="cd")
            if(s=="..") go_back();
            else go_forward(s);
        else if(cmd[0]=='t') touch(s);
        else if(cmd[0]=='m') mkdir(s);
        else if(cmd=="ls") ls();
        else if(cmd=="rm") rm(s);
        else rmdir(s);
    }
}

但是我不能放弃治疗

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
using namespace std;
int cnt,Q,now_data;
string a,b;
struct Document{        //文件夹 
    vector <int> son;   //保存当前文件夹里面的子目录地址。
    int father;         //保存当前文件夹父目录的地址。 
    string name;        //当前文件夹的名字。 
    bool flag;          //flag =1 表示为 文件 0表示为文件夹  2表示被删除 
}document[1001];
void Init_system()
{
    cin>>Q;
    now_data=0;document[0].father=-1;
    for (int i=0;i<=1000;i++)
    document[i].flag=-1;
}
int find_name(int &now_data,string name,int flag) //flag=1 查找文件 否则查找文件夹 
{
    if(flag==1) 
    {
        for (int i=0;i<document[now_data].son.size();i++)
        {
            int new_data=document[now_data].son[i];
            if((document[new_data].name==name)&&(document[new_data].flag==1)) 
            return new_data;

        }
        return -1;
    }
    if(flag==0) 
    {
        for (int i=0;i<document[now_data].son.size();i++)
        {
            int new_data=document[now_data].son[i];
            if((document[new_data].name==name)&&(document[new_data].flag==0)) 
            return new_data;

        }
        return -1;
    }

}
void Build_Document(int &now_data,string name)//创建文件夹 
{
    int iter=find_name(now_data,name,0);
    if(iter!=-1) 
        cout<<"Directory already exists!"<<endl; 
    else
    {
        document[now_data].son.push_back(++cnt);
        document[cnt].father=now_data;
        document[cnt].name=name;
        document[cnt].flag=0;
    }

} 
void Build_File(int &now_data,string name)//创建文件 
{
    int iter = find_name(now_data,name,1);
    if(iter!=-1) 
        cout<<"File already exists!"<<endl; 
    else
    {
        document[now_data].son.push_back(++cnt);
        document[cnt].father=now_data;
        document[cnt].name=name;
        document[cnt].flag=1;
    }

} 
void Enter_SD(int &now_data,string name)  //进入子目录 
{
    int iter = find_name(now_data,name,0); //注意子目录的必须是一个文件夹才可以进入 
    if(iter!=-1)
        now_data=iter; 
    else 
        cout<<"No such directory!"<<endl; 
}
void Enter_FD(int &now_data)  //进入父目录
{
    if(document[now_data].father!=-1)
        now_data=document[now_data].father;
    else
        cout<<"No parent directory!"<<endl; 
}   
void Delete_File(int &now_data,string name)//删除文件 
{
    int iter = find_name(now_data,name,1);
    if(iter!=-1)
        document[iter].flag=2; //2表示该地址的文件已经删除 
    else
        cout<<"No such file!"<<endl; 
}
void Delete_Document(int &now_data ,string name)//删除文件夹 
{
    int iter = find_name(now_data,name,0);
    if(iter!=-1)
        document[iter].flag=2; //2表示该地址的文件已经删除 
    else
        cout<<"No such directory!"<<endl; 
}
void Print(int &now_data)      //输出当前子目录的所有文件 
{
    for (int i=0;i<document[now_data].son.size();i++)
    {
        int v=document[now_data].son[i];
        string name=document[v].name;
        int iter=document[v].flag; 
        if(iter != 2){         //判断是否删除 
            if( iter == 0) cout<<name<<" <D>"<<endl; 
            if( iter == 1) cout<<name<<" <F>"<<endl; 
        } 
    }
    //cout<<endl;
}
int main()
{
    freopen("nacumegu.in","r",stdin);
        //freopen("nacumegu.out","w",stdout); 
    Init_system();
    while(Q--)
    {
       cin>>a;if(a!="ls") cin>>b;
         if(a=="cd"&&b!="..")       Enter_SD(now_data,b);
         else if(a=="cd"&&b=="..")  Enter_FD(now_data);
         else if(a=="touch")        Build_File(now_data,b); 
         else if(a=="rm")           Delete_File(now_data,b);
         else if(a=="mkdir")        Build_Document(now_data,b);
         else if(a=="rmdir")        Delete_Document(now_data,b);
         else if(a=="ls")           Print(now_data);
    }
    return 0;
}        

呵呵哒
今天一如既往的吃枣药丸

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值