题目描述
本题译自 BalticOI 2014 Day1 T2「Three Friends」
给定一个字符串 S,先将字符串 S 复制一次(变成双倍快乐),得到字符串 T,然后在 T 中插入一个字符,得到字符串 U。
给出字符串 U,重新构造出字符串 S。
所有字符串只包含大写英文字母。
输入格式
第一行一个整数 N,表示字符串 U 的长度。
第二行一个长度为 N 的字符串,表示字符串 U。
输出格式
一行一个字符串,表示字符串 S。
特别地:
- 如果字符串无法按照上述方法构造出来,输出
NOT POSSIBLE
; - 如果字符串 S 不唯一,输出
NOT UNIQUE
。
时间500ms 内存256mb
样例1:
输入:
7
ABXCABC
输出:
ABC
样例2:
输入:
6
ABCDEF
输出:
NOT POSSIBLE
样例3:
输入:
9
ABABABABA
输出:
NOT UNIQUE
题解
由于结果字符串为复制一次再插入一个字符,所以当字符串长度为偶数时,直接输出NOT POSSIBLE。既然字符串U为字符串S复制一次再插入一个字符,假设将U分为前后两段的话,如果S存在,则S一定在前半段或者后半段中。
将字符串U两次分为两段,第一次t1,t2;第二次t3,t4;(看答案是不是唯一)。比如当U=”ABXCABC“时,t1=”ABXC“,t2=”ABC“;t3=”ABX“,t4=”CABC“;每一次比较的时候,当字符不一样就次数加1,如果次数大于1时,说明至少要插入两个字符才相等,不符合题意。
下面附上源码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <cstring>
using namespace std;
int n;
string str;
int main()
{
scanf("%d", &n);
cin >> str;
//cin >> str;
if (n % 2 == 0)
{
printf("NOT POSSIBLE\n");
return 0;
}
string t1(str,0,n/2+1), t2(str,n/2+1,n/2), t3(str,0,n/2), t4(str,n/2,n/2+1);
//cout << t1 << endl << t2 << endl << t3 << endl << t4 << endl << endl;
bool f1 = true, f2 = true;
int cnt1 = 0;
for (int i = 0, j = 0; j < t2.size();) //t2是短的那个
{
if (cnt1 > 1)break; //中止2次,不可能成立
if (t1[i] == t2[j])
{
i++;
j++;
}
else
{
cnt1++;
i++;
}
}
if (cnt1 > 1)f1 = false;
if (f1 && t2 == t3)
{
cout << t2 << endl;
return 0;
}
int cnt2 = 0;
for (int i = 0, j = 0; i < t3.size();) //t3是短的那个
{
if (cnt2 > 1)break; //中止2次,不可能成立
if (t3[i] == t4[j])
{
i++;
j++;
}
else
{
cnt2++;
j++;
}
}
if (cnt2 > 1)f2 = false;
if (!f1 && !f2) {
printf("NOT POSSIBLE\n");
return 0;
}
if (f1 && f2 && t2 != t3) {
printf("NOT UNIQUE\n");
return 0;
}
if (f1)cout << t2 << endl;
if (f2 && t2 != t3)cout << t3 << endl;
return 0;
}
输出可能有点乱,但是没有影响最终结果,欢迎大佬指正。