今天花式GG
先放出了不明所以的三道题
伪
A 题
问题描述:
Bob 有 n 个士兵,他们排成一列按照从左到右编号为 1 到 n,每个士兵都有自己的 IQ 值,
Bob 喜欢有序的东西,他想要让这些士兵按照 IQ 的大小从小到大排序。于是 Bob 决定进行
m 次操作,每次选一个士兵,让他开始整理部队。当士兵被选中的时候,士兵会向后的士兵
(编号大于该士兵)发出指令。但是因为 IQ 的原因,只有 IQ 低于该士兵的士兵才会听从
指令。那么这些士兵会按照 IQ 从小到大顺序重新排列在这些士兵之前的位置上,并重新编
号。那么 Bob 想知道,当他选出一些士兵之后,总体士兵 IQ 的逆序对有多少个。
输入:
第一行包含三个整数 n,m,表示士兵的个数和 Bob 操作的次数。
接下来 n 个数字,a1,a2an(ai<1e9),分别表示编号 1,2n 的士兵的 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= |
---|---|---|---|
1 | 2 | 6 | 14989 |
2 | 984 | 7 | 21726 |
3 | 6168 | 8 | 100000 |
4 | 10470 | 9 | 100000 |
5 | 19168 | 10 | 100000 |
不说别的,题解贪心
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;
}
呵呵哒
今天一如既往的吃枣药丸