病毒(信息学奥赛一本通-T1396)

本文介绍了一种算法,该算法能够通过被病毒感染并重新排序的字典来恢复原始文档。通过分析字典中单词间的相对顺序变化,算法可以找出病毒替换字母的规律,进而还原文档。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【题目描述】

有一天,小y突然发现自己的计算机感染了一种病毒!还好,小y发现这种病毒很弱,只是会把文档中的所有字母替换成其它字母,但并不改变顺序,也不会增加和删除字母。

现在怎么恢复原来的文档呢!小y很聪明,他在其他没有感染病毒的机器上,生成了一个由若干单词构成的字典,字典中的单词是按照字母顺序排列的,他把这个文件拷贝到自己的机器里,故意让它感染上病毒,他想利用这个字典文件原来的有序性,找到病毒替换字母的规律,再用来恢复其它文档。

现在你的任务是:告诉你被病毒感染了的字典,要你恢复一个字母串。

【输入】

第一行为整数K(≤50000),表示字典中的单词个数。

以下K行,是被病毒感染了的字典,每行一个单词。

最后一行是需要你恢复的一串字母。

所有字母均为小写。

【输出】

输出仅一行,为恢复后的一串字母。当然也有可能出现字典不完整、甚至字典是错的情况,这时请输出一个0。

【输入样例】

6
cebdbac
cac
ecd
dca
aba
bac
cedab

【输出样例】

abcde

【源程序】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#include<set>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 50001
#define MOD 123
#define E 1e-6
using namespace std;
int n;
int a[N][101],g[27][27];
int enter[27],vis[27],sum[27];
int cnt;
int p;
void judge(int x,int y)
{
    if(a[x][y]==0||a[x+1][y]==0)
        return ;
    if(a[x][y]!=a[x+1][y])
    {
        g[a[x][y]][a[x+1][y]]=1;
        enter[a[x+1][y]]++;
    }
    else
        judge(x,y+1);
}
bool topsort()
{
    for(int i=1;i<=27;++i)
        if(vis[i])
            cnt++;
    for(int i=1;i<n;++i)
        judge(i,1);

    int work,temp;
    while(p!=cnt)
    {
        work=0;
        for(int i=1;i<=cnt;++i)
        {
            if(enter[i]==0)
            {
                temp=i;
                enter[i]=-1;
                work++;
            }
        }
        if(work!=1)
            return false;
        sum[++p]=temp;
        for(int i=1;i<=cnt;++i)
        {
            if(g[temp][i])
            {
                g[temp][i]=0;
                enter[i]--;
            }
        }
    }
    return true;
}
int main()
{
    cin>>n;
    for(int i=1;i<=(n+1);i++)
    {
        string str;
        cin>>str;
        for(int j=0;j<str.size();j++)
        {
            a[i][++a[i][0]]=int(str[j]+1-'a');
            vis[str[j]+1-'a']=1;
        }
    }

    if(!topsort())
        cout<<0;
    else
    {
        for(int i=1;i<=a[n+1][0];++i)
        {
            for(int j=1;j<=cnt;++j)
            {
                if(a[n+1][i]==sum[j])
                {
                    cout<<char(j-1+'a');
                    break;
                }
            }
        }
    }
    return 0;
}

 

### 关于信息学奥赛一本提高篇讲义 PDF 的获取 目前,《信息学奥赛一本》作为国内广泛使用的竞赛教材之一,其内容涵盖了从入门到高级的各种知识点和习题。对于提高篇的具体讲义或 PDF 文件下载需求,需要注意以下几点: #### 合法性和版权说明 根据已知信息[^3],该书部分内容来源于 NOIP 原题以及网络资源整理而成。因此,在寻求相关讲义或 PDF 资料时,应优先考虑合法渠道以尊重知识产权。 #### 获取途径 1. **官方购买** 官方出版的纸质版或电子版是最可靠的来源。可以过各大电商平台(如京东、当当网)或者出版社官方网站查询并购买正版书籍。 2. **配套学习资源** 如果已经拥有实体书,则可以访问书中提到的学习平台链接 http://212.129.250.124:88/home 使用测试账号 `xmvip` 和密码 `888666` 登录体验在线题库及部分教学视频[^2]。虽然此站点可能不提供完整的 PDF 版本,但它包含了大量与提高篇相关的题目解析和讲解材料。 3. **第三方教育机构** 某些专注于信息学奥林匹克竞赛培训的教育机构可能会提供额外的教学辅助资料,包括但不限于 PPT 课件、练习册等。例如 B 站上的免费课程分享也能够帮助理解相关内容[^1]。 4. **社区论坛交流** 加入一些活跃的信息学爱好者圈子(QQ群/微信群),过与其他同学互动或许能获得更多非正式但实用的学习建议甚至共享文档。 #### 注意事项 - 不推荐直接在网络上搜索非法上传的盗版文件,这不仅违反法律还可能存在病毒风险。 - 若仅需了解某些特定章节的知识点而非整本书的内容,可尝试利用搜索引擎查找对应主题的文章或博文解释;比如关于 C++ 编程过渡至 Python 或反之亦然的经验总结就很有价值[^4]。 以下是快速排序的一个简单实现例子供参考: ```python def quick_sort(arr): if len(arr) <= 1: return arr else: pivot = arr[len(arr)//2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left)+middle+quick_sort(right) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值