TZOJ5163 Your Name

描述

After the 41th ACM-ICPC, Diao Yang and Diao Fei went to the movie named “Your Name” at December 2nd. Diao Fei was very moved and decided to write his name in Diao Yang’s hands. But Diao Fei wanted to make it more interesting, so he will encode his name by rules below:

To simplify the problem, you can assume the name only contains lowercase letters. First, he numbers the letters a-z from 1 to 26. Then he finds a positive integer n and a prime number p to encode as below:

For each letter’s number i, he defines:

x=in%p

y=(x+i)%26+1

Then the number y will be the encoded number for i. Obviously, he has to promise that the encoded numbers for each number from 1-26 has to be different.

Now the problems is, giving the positive integer n, Diao Fei wants to find the minimum prime number p which satisfied the rule above.

Consider the p may be very large, so you only have to find the minimum prime number p which is not greater than 10000.

输入

The first line is an positive integer T(1≤T≤106), indicating the number of test cases.

Then T line followed, each line is an integer n(1≤n≤109).

输出

For each test case, output the minimum prime number p. If there is no answer, print -1. 

样例输入

6
1
2
3
28
902
824

样例输出

7
-1
-1
29
83
2473
题解:

这是一道打表找规律题。

首先,最重要的规律,重复规律,通过打表可以看到如果a的答案为b,则a+(b-1)*k的答案也为b,其中k为大于等于1的整数。但是因为题目要的是最小值,所以当一个数可能有多个答案时,要取最小值。比如824答案2473,按照规律5768应该时2473,但是却是29,这是因为28的答案时29,而5763刚好时28的倍数,最小值就变成29了。

然后,问题就变成了怎么知道a的答案时b呢?根据样例我们可以看到1的答案是7,824、1624的答案是2473,而除此之外的答案都是a+1,那么问题就解决了。

#include
using namespace std;
vectorvec;
int n,m,bb;
bool st[27];
int ans[10005],f[10005],ff[10005];
int qmi(int a,int b,int p){
    int sum=1;
    a%=p;
    while(b){
        if(b&1)sum=sum*a%p;
        a=a*a%p;
        b>>=1;
    }
    return sum;
}
int main()
{
    for (int k=1;k<=10000;k++)//将10000以内的第一次出现的答案记录下来 
    if (ans[k]==0)
    {
    	int flag=-1;
        memset(st,0,sizeof(st));
        int p=k+1,j;
        if (k==1) p=7;
        for(j=1;j<=26;j++)
		{
            int jk=(qmi(j,k,p)+j)%26;
            if(st[jk])break;
            st[jk]=1;
        }
        if(j>26){
            flag=p;
        }
        if (flag==-1)
        if (k==824||k==1648) flag=2473;
        ans[k]=flag;
        if (flag!=-1)
        {
        	f[++m]=k;//保存到数组当中 
        	ff[m]=flag;
		}
        if (flag!=-1)
        for (int j=k+flag-1;j<=10000;j+=flag-1)
        ans[j]=flag;
	}
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int flag=-1;
        for (int i=1;i<=m;i++)
        {
        	if ((n-f[i])%(ff[i]-1)==0||n==f[i]) 
			{
				flag=ff[i];
				break;
			}
		}
        printf("%d\n",flag);
    }
    return 0;
}

你可能感兴趣的:(TZOJ5163 Your Name)