noip模拟题11.8

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NOIP(全国青少年信息学奥林匹克竞赛)是中国国内最高水平的信息学竞赛之一,是计算机领域的重要赛事。针对NOIP模拟题,通常是为了帮助参赛者熟悉比赛形式和题型,提供足够的训练机会。 数据下载是NOIP比赛中的一个重要环节,因为参赛者需要根据提供的数据集进行程序开发和测试。数据下载一般通过网络进行,参赛者需要在指定的时间段内下载数据集到自己的计算机上。 在进行NOIP模拟题数据下载时,我们可以按照以下步骤进行操作: 1. 确认下载链接:NOIP官方会提供下载数据集的链接或者FTP地址,参赛者需要确认链接是否可用和正确。 2. 选择下载工具:根据自己的需求,参赛者可以选择合适的下载工具进行操作。常见的下载工具有浏览器内置下载工具、迅雷、IDM等,可以根据个人的习惯和需求选择合适的下载工具。 3. 打开下载工具:根据所选择的下载工具类型,打开对应的软件,进入下载界面。 4. 输入下载链接:将NOIP提供的数据集下载链接复制粘贴到下载工具的链接输入框中,点击确定或开始进行下载。 5. 等待下载完成:根据数据集的大小和网络速度不同,下载时间会有所变化。参赛者需要耐心等待下载完成,确保数据集完整地保存到自己的计算机上。 6. 验证数据完整性:下载完成后,参赛者需要验证数据集的完整性,确保所有文件都成功地保存到指定位置。可以进行文件大小的比对或者逐个文件的校验来检查数据完整性。 通过以上步骤,参赛者可以成功地进行NOIP模拟题数据的下载。在实际比赛中,一个高效的数据下载过程可以提高参赛者的准备时间和竞争力,确保能够充分利用所提供的数据集进行开发和测试。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值