BZOJ 3916 friend文字列hash
1902 ワード
タイトルの説明
3人の親友が一緒にゲームをするのが好きで、A君は次の文字列Sを書いて、B君はそれをコピーしてTを得て、C君はTの任意の位置(首尾を含む)に1つの文字を挿入してUを得て、今あなたはUを得て、Sを見つけてください.
入力
1行目の数Nは、Uの長いを表す.
2行目の文字列Uは、Uが大文字で構成されていることを保証します.
しゅつりょく
1行出力、Sが存在しなければ「NOT POSIBLE」を出力.Sが一意でない場合は「NOT UNIQUE」を出力.そうでなければ出力S.
サンプル入力
Sample Input1: 7 ABXCABC Sample Input2: 6 ABCDEF Sample Input3: 9 ABABABABA
サンプル出力
Sample Output1: ABC Sample Output2: NOT POSSIBLE Sample Output3: NOT UNIQUE
问题解:まず性质を见つけて、偶数の长さの一定は存在しないで、直接出力します.奇数の長さについては、そっくりの列が連なっているのでhashを直接思いつき、hash値が等しければ同じ列となり、どこに文字が挿入されているのか分からないので位置を列挙し、位置が変化しているため、対応する分割された2つの列も異なるので、先に列の接頭辞を処理し、直接加算して減算すればよい.この問題のもう一つの性質は,挿入位置が前半の場合,(n/2+1~~n)は必ず最初の列であり,挿入位置が後半の場合,(1~~n/2)は必ず最初の列である.
まとめ:hashは文字列を処理する有力なツールであり、hash値は通常大きいのでunsigned long longで格納することに注意してください.どんなテーマを手に入れても、まず10分で法則や性質があるかどうかを考えて、往々にして法則、性質を見つけて相応のアルゴリズムを付き合うことができます.
3人の親友が一緒にゲームをするのが好きで、A君は次の文字列Sを書いて、B君はそれをコピーしてTを得て、C君はTの任意の位置(首尾を含む)に1つの文字を挿入してUを得て、今あなたはUを得て、Sを見つけてください.
入力
1行目の数Nは、Uの長いを表す.
2行目の文字列Uは、Uが大文字で構成されていることを保証します.
しゅつりょく
1行出力、Sが存在しなければ「NOT POSIBLE」を出力.Sが一意でない場合は「NOT UNIQUE」を出力.そうでなければ出力S.
サンプル入力
Sample Input1: 7 ABXCABC Sample Input2: 6 ABCDEF Sample Input3: 9 ABABABABA
サンプル出力
Sample Output1: ABC Sample Output2: NOT POSSIBLE Sample Output3: NOT UNIQUE
问题解:まず性质を见つけて、偶数の长さの一定は存在しないで、直接出力します.奇数の長さについては、そっくりの列が連なっているのでhashを直接思いつき、hash値が等しければ同じ列となり、どこに文字が挿入されているのか分からないので位置を列挙し、位置が変化しているため、対応する分割された2つの列も異なるので、先に列の接頭辞を処理し、直接加算して減算すればよい.この問題のもう一つの性質は,挿入位置が前半の場合,(n/2+1~~n)は必ず最初の列であり,挿入位置が後半の場合,(1~~n/2)は必ず最初の列である.
まとめ:hashは文字列を処理する有力なツールであり、hash値は通常大きいのでunsigned long longで格納することに注意してください.どんなテーマを手に入れても、まず10分で法則や性質があるかどうかを考えて、往々にして法則、性質を見つけて相応のアルゴリズムを付き合うことができます.
#include
#include
#include
#include
#define N 2000010
using namespace std;
int n,Hash[N],tmp[N],ans,flag=0,opt;
char str[N];
int main()
{
scanf("%d%s",&n,str+1);
if(!(n%2))
{
printf("NOT POSSIBLE
");
return 0;
}
tmp[0]=1;
for(int i=1;i<=n;i++) Hash[i]=Hash[i-1]*131+str[i],tmp[i]=tmp[i-1]*131;
unsigned long long x,y;
for(int i=1;i<=n;i++)
{
if(i<=n/2) x=Hash[n/2+1]-Hash[i]*tmp[n/2+1-i]+Hash[i-1]*tmp[n/2-i+1];
else x=Hash[n/2];
if(i<=n/2+1) y=Hash[n]-Hash[n/2+1]*tmp[n/2];
else y=Hash[n]-Hash[i]*tmp[n-i]+(Hash[i-1]-Hash[n/2]*tmp[i-1-n/2])*tmp[n-i];
if(x==y)
{
if(flag && ans!=x)
{
printf("NOT UNIQUE
");
return 0;
}
flag=1;ans=x;opt=i;
}
}
if(!flag)
{
printf("NOT POSSIBLE
");
return 0;
}
int cnt=1;
for(int i=1;cnt<=n/2;i++)
if(i!=opt)
cout<