军训快乐

今天给大家讲一个这个题,害得我VJ上僵了一周了(好吧我承认我上周晚上和室友开黑去了,没有好好学习),今天调试了很久,终于弄懂KMP了。

首先就是找除了这一位的最大前缀和最大后缀的匹配位数,然后设成next 数组,再和要匹配的串进行比较,如果哪一位不匹配了,就都回退一位,然后调用next数组,再进行这一位的比较。

One of the most useful tools nowadays are text editors, their use is so important that the Unique Natural Advanced Language (UNAL) organization has studied many of the benefits working with them.

They are interested specifically in the feature "find", that option looks when a pattern occurs in a text, furthermore, it counts the number of times the pattern occurs in a text. The tool is so well designed that while writing each character of the pattern it updates the number of times that the corresponding prefix of the total pattern appears on the text.

Now the UNAL is working with the editor, finding patterns in some texts, however, they realize that many of the patterns appear just very few times in the corresponding texts, as they really want to see more number of appearances of the patterns in the texts, they put a lower bound on the minimum number of times the pattern should be found in the text and use only prefixes of the original pattern. On the other hand, the UNAL is very picky about language, so they will just use the largest non-empty prefix of the original pattern that fit into the bound.

Input

The first line contains the text A (1 ≤ |A| ≤  105) The second line contains the original pattern B (1 ≤ |B| ≤  |A|) The third line contains an integer n (1 ≤ n ≤  |A|) - the minimum number of times a pattern should be found on the text.

Output

A single line, with the prefix of the original pattern used by the UNAL, if there is no such prefix then print "IMPOSSIBLE" (without the quotes)

Examples

Input
aaaaa
aaa
4
Output
aa
Input
programming
unal
1
Output
IMPOSSIBLE
Input
abracadabra
abra
1
Output
abra
Input
Hello World!
H W
5
Output
IMPOSSIBLE
#include <iostream>
#include<string.h>
#include<math.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int next[10010];
char temp[10010];
char s[10010],t[10010];
int getnext(int len2)
{
    int i=0,j=-1;
    next[0]=-1;
    while(i<len2)
    {
        if(j==-1||t[i]==t[j])
        {
            i++;
            j++;
            next[i]=j;
        }
        else
            j=next[j];
    }
}
int kmp(int len1,int len2)
{
    int i=0,j=0,ans=0;
    memset(next,0,sizeof(next));
    getnext(len2);
    while(i<len1)
    {
        if(j==-1||s[i]==t[j])
        {
            i++;
            j++;
        }
        else
            j=next[j];
        if(j==len2)
        {
            i--;
            ans++;
            j=next[j-1];
        }
    }
    return ans;
}
int main()
{
    int k,i,mid;
    gets(s);
    gets(t);
    cin>>k;
    int l=0,r=strlen(t);
    int ans=0;
    while(l<=r)
    {
         mid=(l+r)/2;
        for(i=0; i<mid; i++)
        {
            temp[i]=t[i];
        }
        if(mid==0)
            break;
        if(kmp(strlen(s),mid)<k)
        {
            r=mid-1;
        }
        else
        {
            ans=mid;
            l=mid+1;
        }

    }
    if(mid==0)
    {
        cout<<"IMPOSSIBLE"<<endl;
        return 0;
    }
    for(i=0; i<ans; i++)
    {
        cout<<temp[i];
    }
    cout<<endl;
    return 0;
}

这个题就先按照要求用a[1,m]构造出a[1,n],然后这里n == 3e7,所以如果采用快速的比较排序算法如归并排序快速排序的时间复杂度是O(nlogn)会超时,因此我们想到可以使用线性排序方法桶排序(或者说计数排序),建一个数组cnt[3e7+8],扫一遍a数组,对于每一个ai,cnt[a[i]]++,最后扫一遍cnt数组,就可以把ai排好序了。

#include <iostream.>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
const int mod=3*1e7;
int a[30000000];
int cnt[30000000];
int main()
{
    int n,m,q,i,x;
    cin>>n>>m>>q;
for(i=1;i<=m;i++)
{
    cin>>a[i];
}
int t=1;
    for(i=m+1;i<=n;i++)
    {
        a[i]=(a[i-m]+a[i-m+1])%mod;
    }
    int psr=0;
    for(i=1;i<=n;i++)
        cnt[a[i]]++;
 for(i=0;i<mod;i++)
 {
     while(cnt[i])
     {
         a[psr]=i;
         psr++;
         cnt[i]--;
     }

 }
 for(i=0;i<q;i++)
 {
     cin>>x;
     cout<<a[x-1]<<endl;
 }
    return 0;

}

这个题就是要知道平面内判断两点共线的公式,如果共线过了就进行标记。

a1=(x1,y1,z1)
a2=(x2,y2,z2 )
a1→=(x1,y1,z1)平行于a2→=(x2,y2,z2)
x1×y2=x2×y1
y1×z2=y2×z1
z1×x2=z2×x1
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct node
{
    int x;
    int y;
    int z;
}a[5005];
int str[5005];
int main()
{
    int n,i,j;
    cin>>n;
    cin>>a[0].x>>a[0].y>>a[0].z;
    for(i=1;i<n;i++)
    {
        cin>>a[i].x>>a[i].y>>a[i].z;
        a[i].x-=a[0].x;
        a[i].y-=a[0].y;
        a[i].z-=a[0].z;
    }
    int ans=0;
    for(i=1;i<n;i++)
    {
        if(str[i])
            continue;
        ans++;
        for(j=i+1;j<n;j++)
        {
            if(a[i].x*a[j].y==a[i].y*a[j].x&&a[i].y*a[j].z==a[i].z*a[j].y&&a[i].z*a[j].x==a[i].x*a[j].z)
            {
               str[j]=1;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}
/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         I have a dream!A AC deram!!
 orz orz orz orz orz orz orz orz orz orz orz
 orz orz orz orz orz orz orz orz orz orz orz
 orz orz orz orz orz orz orz orz orz orz orz

*/

学弟学妹问可怕学姐最近为什么不种太阳了。

延期多好啊,为什么要种太阳?

猜你喜欢

转载自www.cnblogs.com/kepa/p/9618017.html