集训考试题(CF510C Fox And Names的简化版)

题目描述
给定n个由小写字母组成的字符串,请你求出一个字母表顺序,使得这n个字符串是按照字典序升序排列的,数据保证存在合法的字母表顺序。
如果存在多个解,输出字典序最小的那个。

输入格式
第一行一个整数n.接下来n行,每行一个字符串。
输出格式
一行,一个a到z各出现一次的字符串,表示字母表顺序 。

样例读入:
10
petr
egor
endagorion
feferivan
ilovetanyaromanova
kostka
dmitriyh
maratsnowbear
bredorjaguarturnik
cgyforever
样例输出:
aghjlnopefikdmbcqrstuvwxyz

先水一下在考场上的骗分思路:
可以发现的是,非常有意思的,把所有的字符串的首字母提取出来,以样例为例,也就是:
peefikdmbc
去重后就是:
pefikdmbc
然后发现它在样例输出里存在,接着又发现,把其他的,没有在这个小串里出现的字幕按照正常的字母表顺序接在这个小串两边,就凑出了样例,
前半段自然是好凑,而后半段,我们则直接输出这个小串的首字母,也就是p,在字母表后没有出现的字母堆在后面,就凑出了样例:
前半段自然是:aghjlno
后半段自然是:qrstuvwxyz
然后我们就得到了样例输出:aghjlnopefikdmbcqrstuvwxyz
然后可能是存在某种正确性,但是一般不是字典序最小,但是我依旧骗到了大量的部分分

接着我们讲正解思路:
我们想要使得字符串的顺序有一个优先级,就意味着最基本的,他们的首字母有一个优先级
然后要是上下两个字符串的前半部分相等,那么就可以确定这之后的头一个字母的优先级
然后我们假设在一张图上优先级低的指向了优先级高的,也就是建立了一个拓扑序
我们根据拓扑序确定一个顺序。
优先级低的指向优先级高的,也就是将优先级高的的字母的入读加一
先将所有入度为0的存入答案数组,再按照拓扑序记录答案,最后输出即可
因为题目保证了一定合法,所以我们可以不考虑不合法的情况,但是如果一定有不合法的情况,我们判断也很简单
1.若两个字符串,一个字符串能够在另一个字符串中找到,且较长的字符串在短的字符串的上面,这是显然不合法的
2.若最后拓扑结束后,答案数组里存的字母不到26个,显然是不合法的

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1100;
 4 int n, top = 0;
 5 char s[maxn][maxn], ans[maxn];
 6 int in[maxn], lin[maxn][maxn];//lin表示两个字符串连接一条边bulabulabula 
 7 bool flag = 1;
 8 
 9 inline int read() {
10     int x = 0, y = 1;
11     char ch = getchar();
12     while(!isdigit(ch)) {
13         if(ch == '-') y = -1;
14         ch = getchar();
15     }
16     while(isdigit(ch)) {
17         x = (x << 1) + (x << 3) + ch - '0';
18         ch = getchar();
19     }
20     return x * y;
21 }
22 
23 queue<int> q;
24 inline bool topsort_solve() {
25     for(int i = 0; i < 26; ++i)
26         if(!in[i]) {
27             q.push(i);
28             ans[++top] = char(i + 'a');
29         }
30     while(!q.empty()) {
31         int k = q.front(); q.pop();
32         for(int i = 0; i < 26; ++i)
33             if(lin[k][i]) {
34                 in[i]--;
35                 if(!in[i]) {
36                     ans[++top] =char(i + 'a');
37                     q.push(i);
38                 }
39             }
40     }
41     if(top < 26) return 0;
42     else return 1;
43 }
44 
45 int main() {
46     memset(in, 0, sizeof(in));
47     memset(lin, 0, sizeof(lin));
48     n = read();
49     for(int i = 0; i < n; ++i)
50         cin >> s[i];
51     for(int i = 0; i < n - 1; ++i) {
52         int len1 = strlen(s[i]);
53         int len2 = strlen(s[i + 1]);
54         int j = 0;
55         while(j < len1 && j < len2 && s[i][j] == s[i + 1][j]) j++;
56         if(j < len1 && j < len2) {
57             if(!lin[s[i][j] - 'a'][s[i + 1][j] - 'a']) {//建立top关系//建图 
58                 lin[s[i][j] - 'a'][s[i + 1][j] - 'a'] = 1;
59                 in[s[i + 1][j] - 'a']++;
60             }
61         }
62         else if(len1 > len2) flag = 0;
63     }
64     if(!flag) cout << "Impossible" << '\n';
65     else if(flag) {
66         flag = topsort_solve();
67         if(!flag) cout << "Impossible" << '\n';
68         else {
69             for(int i = 1; i <= top; ++i)
70                 cout << ans[i];
71             cout << '\n';
72         }
73     }
74     return 0;
75 }

 

转载于:https://www.cnblogs.com/ywjblog/p/9481944.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值