3 solutions
- 
  3题意给一个字符串,看看删去一个字符后前半段和后半段相不相等。 思路首先,字符串长度一定得是奇数,因为字符串删掉一个字符后前后长度要一样。这个一看就知道。 然后开始做题,我们用哈希做。 这个新加入的字符要么在前,要么在后。所以找一个字符删掉然后比较前后是否相等就行了。 这里分前后找,前面找到一个后就直接 break,然后找下一段(找到就代表那一段至少有一个符合要求的字符)但这里要看结果是否唯一,所以要检测有没有多个答案。 总结: - 给的字符串的长度一定是奇数
- 前面找到直接到后面找
- 检测是否有多个答案
 代码#include <bits/stdc++.h> using namespace std; const int N = 2000005,BASE = 2617; int p[N] = {1},h[N],l1,l2,cnt; int sec(int l,int r){ // 区间哈希 return h[r] - h[l - 1] * p[r - l + 1]; } int sub(int l,int r,int x){ // 减去其中一个字母 return sec(l,x - 1) * p[r - x] + sec(x + 1,r); } signed main(int argc, char **argv){ for (int i = 1;i <= N;i++) p[i] = p[i - 1] * BASE; int n;string s,a,b/*不是骂人*/;char c; cin >> n >> s; if (n % 2 == 0){ printf("NOT POSSIBLE"); return 0; } int mid = n + 1 >> 1; for (int i = 1;i <= n;i++){ // 算好整个字符串的哈希 char x = s[i - 1]; h[i] = h[i - 1] * BASE + (x - 'A' + 1); } l1 = sec(1,mid - 1); // 前半段 a = s.substr(0,mid - 1); // 前半段少一个字符的字符串 for (int i = mid;i <= n;i++){ // 暴搜 l2 = sub(mid,n,i); if (l1 == l2){ cnt++; c = 'a'; break; } } l2 = sec(mid + 1,n); // 后半段 b = s.substr(mid,n); // 后半段的字符串 for (int i = 1;i <= mid;i++){ // 暴搜 l1 = sub(1,mid,i); if (l1 == l2){ cnt++; c = 'b'; break; } } // 答案为 0(没有) if (!cnt) printf("NOT POSSIBLE"); // 答案唯一,或添加的字符刚好在中间 else if (cnt == 1 || a == b) cout << (c == 'a'?a:b); // 答案不唯一 else printf("NOT UNIQUE"); return 0; }参考与鸣谢
- 
  1题意题目说的已经很清楚了 有一个字符串 ,对他进行操作: - 将 复制为两份,存在字符串 中
- 在 的某一位置上插入一个字符,得到字符串
 现在给定 ,求 。 思路首先要判断长度是不是奇数,应为只有奇数才说明可能有插入的那一个字符 分两段判断 
 由题意可知 得为奇数,才存在,所以先特判 为偶数的情况。 由题意可知 的长度为 , 设 的长度为 。 因为只插入一个字符,所以如果存在 ,则 的前 个字符或后 个字符中一定有一边是。 所以可以用 substr 函数分别截取前 个字符和后 个字符,再依次匹配检查是否合法。 代码#include<iostream> #include<string> using namespace std; int n; string u; int main() { cin>>n>>u; if(n%2==0)//只有奇数个字符才有可能有S { cout<<"NOT POSSIBLE"; return 0; } int m=n/2; bool fa=0,fb=0; string a=u.substr(0,m); int j=0; for(int i=m;i<n && j<m;i++)//前一段 if(u[i]==a[j]) j++; if(j==m) fa=1; string b=u.substr(n-m,m); j=0; for(int i=0;i<n-m && j<m;i++)//后一段 if(u[i]==b[j]) j++; if(j==m) fb=1; if(fa==0 && fb==0)//不存在 cout<<"NOT POSSIBLE"; else if(fa && fb && a!=b) cout<<"NOT UNIQUE"; else if(fa) cout<<a; else cout<<b; return 0;//完结散花 }
- 
  -1题意题目说的已经很清楚了 有一个字符串 ,对他进行操作: - 将 复制为两份,存在字符串 中
- 在 的某一位置上插入一个字符,得到字符串
 现在给定 ,求 。 思路首先要判断长度是不是奇数,应为只有奇数才说明可能有插入的那一个字符 分两段判断 
 题解原文思路由题意可知 得为奇数,才存在,所以先特判 为偶数的情况。 由题意可知 的长度为 , 设 的长度为 。 因为只插入一个字符,所以如果存在 ,则 的前 个字符或后 个字符中一定有一边是。 所以可以用 substr 函数分别截取前 个字符和后 个字符,再依次匹配检查是否合法。 代码#include<iostream> #include<string> using namespace std; int n; string u; int main() { cin>>n>>u; if(n%2==0)//只有奇数个字符才有可能有S { cout<<"NOT POSSIBLE"; return 0; } int m=n/2; bool fa=0,fb=0; string a=u.substr(0,m); int j=0; for(int i=m;i<n && j<m;i++)//前一段 if(u[i]==a[j]) j++; if(j==m) fa=1; string b=u.substr(n-m,m); j=0; for(int i=0;i<n-m && j<m;i++)//后一段 if(u[i]==b[j]) j++; if(j==m) fb=1; if(fa==0 && fb==0)//不存在 cout<<"NOT POSSIBLE"; else if(fa && fb && a!=b) cout<<"NOT UNIQUE"; else if(fa) cout<<a; else cout<<b; return 0;//完结散花 }
- 1
Information
- ID
- 256
- Time
- 500ms
- Memory
- 256MiB
- Difficulty
- 9
- Tags
- # Submissions
- 26
- Accepted
- 2
- Uploaded By
 
      