T1 智乃
【题目描述】
给你一个字符串 ,你每次可以选择其中一个字符串的一段前缀进行翻转,但是你必须保证这个前缀的长度是偶数。你可以进行无限次 这样的操作,并且如果两个字符串变得相同的时候,你就可以把这两个字符串都删除掉,问最后最少剩下多少个字符串?
【输入格式】
第一行个整数T代表数据组数。
对于每组数据,第一行个整数代表字符串个数。
接下来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≤N≤50。
20个数据,当时乱搞A了一个…
很容易证明:将这个字符串分成两个字符+两个字符+……,两个字符为一组,将一组作为基础,每组可以出现在任何位置,且每组的两个字符可以互换。那么直接排序每组,每组内再排序,就行。要注意:字符串的长度为奇数时,最后一组的第二个设为0。
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int fi,se;
}gg[55][55];
int judge[55],num[55],ans;
int cmp(const node&a,const node&b)
{
if(a.fi!=b.fi)return a.fi<b.fi;
return a.se<b.se;
}
void search(int k)
{
int bbbb=0;
for(int i=1;i<k;i++)
{
if(!judge[i]&&num[i]==num[k])
{
int q=num[i]>>1;
if((num[i]&1)==1)q++;
for(int j=1;j<=q;j++)
{
if(gg[i][j].fi!=gg[k][j].fi||gg[i][j].se!=gg[k][j].se)
break;
if(j==q)
bbbb=1;
}
if(bbbb)
{
ans-=2;
judge[i]=judge[k]=1;
return ;
}
}
}
}
int main()
{
freopen("kahuucino.in","r",stdin);
freopen("kahuucino.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
memset(judge,0,sizeof(judge));
memset(gg,0,sizeof(gg));
int n;
scanf("%d",&n);
ans=n;
for(int i=1;i<=n;i++)
{
int tot=0;
char s[55];
scanf("%s",s+1);
num[i]=strlen(s+1);
if((num[i]&1)==0)
for(int j=1;j<=num[i];j+=2)
{
int x1=s[j]-'a'+1,x2=s[j+1]-'a'+1;
gg[i][++tot].fi=min(x1,x2);
gg[i][tot].se=max(x1,x2);
}
else
{
for(int j=1;j<=num[i]-1;j+=2)
{
int x1=s[j]-'a'+1,x2=s[j+1]-'a'+1;
gg[i][++tot].fi=min(x1,x2);
gg[i][tot].se=max(x1,x2);
}
gg[i][++tot].fi=s[num[i]]-'a'+1;
}
sort(gg[i]+1,gg[i]+1+tot,cmp);
search(i);
}
printf("%d\n",ans);
}
}
T2 麻耶
【问题描述】
油库里是幻想乡特有的一种生物。每只都个战斗力值和能量值。当两只油库里战斗时,总是战斗力高的一位获胜。获胜者的战斗力将变成(自己的原战斗力值-对手的战斗力值+对手的能量值 )。败者将死去。若两油库里战斗力值一样,则同归于尽。
思考熊发现了很多油库里,他想知道通过互相战斗之后油库里中战斗力值+能量值最高的一个可到达多少。你帮他们求出来吗?(假设除了考察那只油库里之外,其他油库里间不会发生战斗)
【输入格式】
第一行是个整数N,代表当前有多少油库里 。
接下来的N行,每一行有两个整数u,v,代表这只油库里的战斗力值和能量值。
【输出格式】
输出一个整数,代表油库里中战斗力值+能量值最高的一个达到多少 。
【样例输入】
2
1 2
2 1
【样例输出】
4
【样例解释】
无。
【数据规模与约定】
对于20%的数据,1≤u,v≤10^3。
对于40%的数据,1≤u,v≤3×10^4。
对于 100%的数据, 1≤u,v≤10^9。
简单贪心。将每只油库里按战斗力从大到小排序,枚举。每枚举到一只油库里进行三个判断:
1、打这只油库里。
2、不打这只油库里。
3、从这只油库里重新开始。
这里解释一下第三个判断。如果之前的油库里打到当前这只油库里,并且如果打这只或不打这只的战斗力+能量还没有直接选当前这只油库里的战斗力+能量大的话,选当前这只。
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
long long fight,power,give,sum;
}gg[100005];
inline int read()
{
int 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*10+ch-'0';ch=getchar();}
return x*f;
}
int cmp(const node&a,const node&b)
{
if(a.fight>b.fight)return true;
else if(a.fight<b.fight)return false;
if(a.fight==b.fight&&a.power>b.power)return true;
else return false;
}
int main()
{
freopen("zyougamaya.in","r",stdin);
freopen("zyougamaya.out","w",stdout);
int n=read();
for(int i=1;i<=n;i++)
{
scanf("%I64d%I64d",&gg[i].fight,&gg[i].power);
gg[i].give=gg[i].power-gg[i].fight;
gg[i].sum=gg[i].power+gg[i].fight;
}
sort(gg+1,gg+n+1,cmp);
for(int i=2;i<=n;i++)
if(gg[i].fight!=gg[i-1].fight&&gg[i-1].fight+gg[i].give+gg[i-1].power>gg[i-1].sum&&gg[i-1].fight+gg[i].give+gg[i-1].power>gg[i].sum)
{
gg[i].fight=gg[i-1].fight+gg[i].give;
gg[i].power=gg[i-1].power;
gg[i].give=gg[i].power-gg[i].fight;
gg[i].sum=gg[i].power+gg[i].fight;
}
else if(gg[i-1].sum>gg[i].sum||(gg[i-1].sum==gg[i].sum&&gg[i-1].power>gg[i].power))
{
gg[i].fight=gg[i-1].fight;
gg[i].power=gg[i-1].power;
gg[i].give=gg[i].power-gg[i].fight;
gg[i].sum=gg[i].power+gg[i].fight;
}
printf("%I64d",gg[n].sum);
return 0;
}
T3 惠
【问题描述】
现在你要实一个文件系统,支持以下操作
cd Directory_Name
如果当前路径下有名为Directory_Name的文件夹,则进入该所对应的文件夹所对应的路径,否则输出“ No such directory!”。cd ..
如果当前路径存在父路径,则返回父路径,否则输出”No parent directory!“。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>(文件)注意:同一路径下文件与文件夹可以同名,但同一路径下文件与文件、文件夹与文件夹不能同名。
初始时当前路径处于根路径下,无父路径。
【输入格式】
第一行为Q,表示有Q个操作。
接下来是Q行,每行输入为以上描述的操作之一。
【输出格式】
输出答案。
【样例输入】
3
mkdir standy
touch totalfrank
ls
【样例输出】
standy <D>
totalfrank <F>
【样例解释】
无
【数据规模与约定】
对于100%的数据,1≤Q≤100,所有文件名字长度不超过200且均为小写字母。
开始用了很多map…结果只A了一个点。啊没看到数据这么水,明明可以乱搞…直接存点、每个点对应的字符串和父文件夹、还有这个点是文件还是文件夹的信息,每次操作扫一遍就行。
代码:
#include<map>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int tot=1,fa[3005],now=1,judge[3005];
string que[3005];
void touch()
{
string s2;cin>>s2;
for(int i=1;i<=tot;i++)
if(que[i]==s2&&fa[i]==now&&judge[i]==1)
{
printf("File already exists!\n");
return ;
}
fa[++tot]=now;
que[tot]=s2;
judge[tot]=1;
}
void mkdir()
{
string s2;cin>>s2;
for(int i=1;i<=tot;i++)
if(que[i]==s2&&fa[i]==now&&judge[i]==2)
{
printf("Directory already exists!\n");
return ;
}
fa[++tot]=now;
que[tot]=s2;
judge[tot]=2;
}
void rmdir()
{
string s2;cin>>s2;
for(int i=1;i<=tot;i++)
if(que[i]==s2&&fa[i]==now&&judge[i]==2)
{
fa[i]=-1;return ;
}
printf("No such directory!\n");
}
void rm()
{
string s2;cin>>s2;
for(int i=1;i<=tot;i++)
if(que[i]==s2&&fa[i]==now&&judge[i]==1)
{
fa[i]=-1;return ;
}
printf("No such file!\n");
}
void sd()
{
string s2;cin>>s2;
if(s2[0]=='.')
{
if(fa[now])
{
now=fa[now];
return ;
}
else{
printf("No parent directory!\n");return ;
}
}
for(int i=1;i<=tot;i++)
if(que[i]==s2&&fa[i]==now&&judge[i]==2)
{
now=i;
return ;
}
printf("No such directory!\n");
}
void ls()
{
for(int i=1;i<=tot;i++)
if(fa[i]==now)
{
cout<<que[i];
if(judge[i]==1)
printf(" <F>\n");
else printf(" <D>\n");
}
}
int main()
{
freopen("nacumegu.in","r",stdin);
freopen("nacumegu.out","w",stdout);
int q;
scanf("%d",&q);
judge[now]=2;
while(q--)
{
string s1;
cin>>s1;
int len=s1.size();
if(len==5)
{
if(s1[len-1]=='h')
touch();
else if(s1[0]=='m')
mkdir();
else rmdir();
}
else
{
if(s1[len-1]=='s')
ls();
else if(s1[len-1]=='m')
rm();
else sd();
}
}
return 0;
}