Codejam Round 1A 2020 Pattern Matching(构造)

2024-04-16 01:18

本文主要是介绍Codejam Round 1A 2020 Pattern Matching(构造),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Problem
Many terminals use asterisks () to signify “any string”, including the empty string. For example, when listing files matching BASH, a terminal may list BASH, BASHER and BASHFUL. For FUL, it may list BEAUTIFUL, AWFUL and BASHFUL. When listing BL, BASHFUL, BEAUTIFUL and BULL may be listed.

In this problem, formally, a pattern is a string consisting of only uppercase English letters and asterisks (*), and a name is a string consisting of only uppercase English letters. A pattern p matches a name m if there is a way of replacing every asterisk in p with a (possibly empty) string to obtain m. Notice that each asterisk may be replaced by a different string.

Given N patterns, can you find a single name of at most 104 letters that matches all those patterns at once, or report that it cannot be done?

Input
The first line of the input gives the number of test cases, T. T test cases follow. Each test case starts with a line with a single integer N: the number of patterns to simultaneously match. Then, N lines follow, each one containing a single string Pi representing the i-th pattern.

Output
For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is any name containing at most 104 letters such that each Pi matches y according to the definition above, or * (i.e., just an asterisk) if there is no such name.

Limits
Time limit: 20 seconds per test set.
Memory limit: 1GB.
1 ≤ T ≤ 100.
2 ≤ N ≤ 50.
2 ≤ length of Pi ≤ 100, for all i.
Each character of Pi is either an uppercase English letter or an asterisk (*), for all i.
At least one character of Pi is an uppercase English letter, for all i.

Test set 1 (Visible Verdict)
Exactly one character of Pi is an asterisk (), for all i.
The leftmost character of Pi is the only asterisk (
), for all i.

Test set 2 (Visible Verdict)
Exactly one character of Pi is an asterisk (*), for all i.

Test set 3 (Visible Verdict)
At least one character of Pi is an asterisk (*), for all i.

Sample

Input

Output

2
5
*CONUTS
*COCONUTS
*OCONUTS
*CONUTS
*S
2
*XZ
*XYZ

Case #1: COCONUTS
Case #2: *

In Sample Case #1, there are other possible answers, including COCOCONUTS and ILIKECOCONUTS. Neither COCONUTSAREGREAT nor COCOANUTS would be acceptable. Notice that the same pattern may appear more than once within a test case.

In Sample Case #2, there is no acceptable name, so the answer is *.

The following cases could not appear in Test Set 1, but could appear in Test Set 2 or Test Set 3:

4
HO
HELLO

HELLO
HE

HELLO and HELLOGOODBYEHELLO are examples of acceptable answers. OTHELLO and HELLOO would not be acceptable.

2
CODE
J
AM
There is no name that matches both patterns, so the answer would be *.

2
CODE*
*JAM
CODEJAM is one example of an acceptable answer.

The following cases could not appear in Test Set 1 or Test Set 2, but could appear in Test Set 3:

2
ACE
BD*
ABCDE and ABUNDANCE are among the possible acceptable answers, but BOLDFACE is not.

2
ACE
BD
There is no name that matches both patterns, so the answer would be *.

2
Q
A
QUAIL and AQ are among the possible acceptable answers here.

round1A感觉好难啊。A,B是构造,C是模拟。想了好久的A,写到第二个点的时候,发现只需要匹配前后缀。然后到了第三个点,发现中间部分只要把所有字符串加上来就好了。本来B题的前两个点也看出了了,只需要输出边上的,但是最后BUG没改完。码力还是不行。。。
题意:
∗ * 可以代表任意字符串,包括空串。
给一系列带 ∗ * 的字符串,求构造一个字符串(不带 ∗ * ,使得其能匹配所有字符串)

思路:
需要考虑的只有前后缀。
构造出来的新串只要加上最长的前缀和最长的后缀,中间部分是所有字符串非前后缀加上来。

如果前缀最长的字符串的前缀,不能通过其后缀匹配其他字符串前缀,那肯定弄不了,后缀同理。

ACNEW
逻辑清晰了点

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <set>
#include <queue>
#include <cmath>
#include <vector>
#include <map>
#include <ctime>
#include <stack>using namespace std;typedef long long ll;
const int maxn = 100 + 7;
int n;
string s[maxn];string get_pre(string &str) {string ans;for(int i = 0;i < str.length();i++) {if(str[i] == '*') break;ans += str[i];}return ans;
}string get_suf(string &str) {string ans;for(int i = str.length() - 1;i >= 0;i--) {if(str[i] == '*') break;ans += str[i];}reverse(ans.begin(),ans.end());return ans;
}bool equal_pre(string &str1,string &str2) {for(int i = 0;i < str2.length();i++) {if(str2[i] == '*') break;if(str1[i] != str2[i]) return false;}return true;
}bool equal_suf(string &str1,string &str2) {int cnt1 = str1.length() - 1,cnt2 = str2.length() - 1;for(int i = str1.length() - 1;i >= 0;i--) {if(cnt1 < 0 || cnt2 < 0) break;if(str2[cnt2] == '*') break;if(str1[cnt1] != str2[cnt2]) return false;cnt1--;cnt2--;}return true;
}bool check(string &pre,string &suf) {for(int i = 1;i <= n;i++) {string pre_now = get_pre(s[i]);if(!equal_pre(pre,pre_now)) return false;string suf_now = get_suf(s[i]);if(!equal_suf(suf,suf_now)) return false;}return true;
}void Print(string &pre,string &suf) {cout << pre;for(int i = 1;i <= n;i++) {for(int j = 0;j < s[i].length();j++) {if(s[i][j] == '*') continue;cout << s[i][j];}}cout << suf << endl;
}int main() {int T;scanf("%d",&T);int kase = 0;while(T--) {scanf("%d",&n);int mx_pre = 0,mx_suf = 0;string pre,suf;for(int i = 1;i <= n;i++) {cin >> s[i];string pre_now = get_pre(s[i]);int len1 = pre_now.length();if(len1 > mx_pre) {mx_pre = len1;pre = pre_now;}string suf_now = get_suf(s[i]);int len2 = suf_now.length();if(len2 > mx_suf) {mx_suf = len2;suf = suf_now;}}printf("Case #%d: ",++kase);if(check(pre,suf)) {Print(pre,suf);} else {cout << "*" << endl;}}return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
#include <string>
#include <vector>using namespace std;string s[1005];
int n;
int mx_s = 0,mx_e = 0;
string sta,ed;bool check1(string a,string b) {//前缀int len1 = a.length(),len2 = b.length();for(int i = 0;i < len1;i++) {if(b[i] == '*') break;if(a[i] != b[i]) return false;}return true;
}bool check2(string a,string b) {//后缀int len1 = a.length(),len2 = b.length();for(int i = len1 - 1,j = len2 - 1;i >= 0 && j >= 0;i--,j--) {if(b[j] == '*') break;if(a[i] != b[j]) return false;}return true;
}void Cin() {for(int i = 1;i <= n;i++) {cin >> s[i];int len = s[i].length();for(int j = 0;j < len;j++) {if(s[i][j] == '*') {if(mx_s < j && j != 0) {mx_s = j;sta = s[i].substr(0,j);}break;}}for(int j = len - 1;j >= 0;j--) {if(s[i][j] == '*') {if(mx_e < len - j && j != len - 1) {ed = s[i].substr(j + 1,len - 1 - j);mx_e = len - 1 - j;}break;}}}
}
bool judge() {for(int i = 1;i <= n;i++) {if(!check1(sta,s[i]) || !check2(ed,s[i])) {return false;}}return true;
}int main() {int T;scanf("%d",&T);int kase = 0;while(T--) {scanf("%d",&n);mx_s = 0,mx_e = 0;sta.clear();ed.clear();Cin();int flag = judge();printf("Case #%d: ",++kase);if(flag) {cout << sta;for(int i = 1;i <= n;i++) {for(int j = 0;j < s[i].size();j++) {if(s[i][j] == '*') continue;cout << s[i][j];}}cout << ed;printf("\n");}else {printf("*\n");}}return 0;
}

这篇关于Codejam Round 1A 2020 Pattern Matching(构造)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907436

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

C++中类的构造函数调用顺序

当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的 构造函数,依次类推,直至到达派生类次数最多的派生次数最多的类的构造函数为止。 简而言之,对象是由“底层向上”开始构造的。因为,构造函数一开始构造时,总是 要调用它的基类的构造函数,然后才开始执行其构造函数体,调用直接基类构造函数时, 如果无专门说明,就调用直接基类的默认构造函数。在对象析构时,其顺序正好相反。

Codeforces Round 971 (Div. 4) (A~G1)

A、B题太简单,不做解释 C 对于 x y 两个方向,每一个方向至少需要 x / k 向上取整的步数,取最大值。 由于 x 方向先移动,假如 x 方向需要的步数多于 y 方向的步数,那么最后 y 方向的那一步就不需要了,答案减 1 代码 #include <iostream>#include <algorithm>#include <vector>#include <string>

Java构造和解析Json数据的两种方法(json-lib构造和解析Json数据, org.json构造和解析Json数据)

在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别。下面首先介绍用json-lib构造和解析Json数据的方法示例。 一、介绍       JSON-lib包是一个beans,collections,maps,java arrays 和XML和JSON互相转换的包,主要就是用来解析Json

leetcode#10. Regular Expression Matching

题目 Implement regular expression matching with support for ‘.’ and ‘*’. '.' Matches any single character.'*' Matches zero or more of the preceding element.The matching should cover the entire input