POJ2767 Reduced ID Numbers -同余定理

题目链接 This is the link

Description

T. Chur teaches various groups of students at university U. Every U-student has a unique Student Identification Number (SIN). A SIN s is an integer in the range 0 ≤ s ≤ MaxSIN with MaxSIN = 106-1. T. Chur finds this range of SINs too large for identification within her groups. For each group, she wants to find the smallest positive integer m, such that within the group all SINs reduced modulo m are unique.

Input

On the first line of the input is a single positive integer N, telling the number of test cases (groups) to follow. Each case starts with one line containing the integer G (1 ≤ G ≤ 300): the number of students in the group. The following G lines each contain one SIN. The SINs within a group are distinct, though not necessarily sorted.

Output

For each test case, output one line containing the smallest modulus m, such that all SINs reduced modulo m are distinct.

Sample Input

2
1
124866
3
124866
111111
987651

Sample Output

1
8

Source

Northwestern Europe 2005

题目大意:求解一个最小正整数,使得其它数对其不同余,

思路:枚举每一个因子,判断因子并判断是否同余,

//暴力枚举时间可以过的去,//367MS,注意其中的枝减

This is the link

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include <iomanip>
#include<list>
#include<queue>
#include<sstream>
#include<stack>
#include<string>
#include<set>
#include<vector>
using namespace std;
#define PI acos(-1.0)
#define EPS 1e-8
#define MOD 1e9+7
#define LL long long
#define ULL unsigned long long     //1844674407370955161
#define INT_INF 0x7f7f7f7f      //2139062143
#define LL_INF 0x7f7f7f7f7f7f7f7f //9187201950435737471
const int dr[]={0, 0, -1, 1, -1, -1, 1, 1};
const int dc[]={-1, 1, 0, 0, -1, 1, -1, 1};
// ios.sync_with_stdio(false);
// 那么cin, 就不能跟C的scanf,sscanf,getchar,fgets之类的一起使用了。
#define N 1000000
int a[N+5];
bool p[N+5];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;++i)
            scanf("%d",&a[i]);
        int find;
        for(int i=1; ; ++i)
        {
            find=i;
            for(int j=0;j<=i;++j)//将余数归零
                p[j]=false;
            for(int j=0;j<n;++j)
            {
                int mod=a[j]%i;
                if(p[mod])//表示i有同余的
                {
                    find=0;
                    break;
                }
                p[mod]=true;;//表示这个数的余数
            }
            if(find)
                break;
        }
        printf("%d\n",find);
    }
    return 0;
}

//另一种思路,使用同余定理

同余式 : a ≡ b (mod m) (即 a%m == b%m)

简单粗暴的说就是:若 a-b == m 那么 a%m == b%m

使用同余定理sha筛选出一部分来,然后逐个枚举,判读是否不同余

//感觉用时比上一个长  782MS

This is the link

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include <iomanip>
#include<list>
#include<queue>
#include<sstream>
#include<stack>
#include<string>
#include<set>
#include<vector>
using namespace std;
#define PI acos(-1.0)
#define EPS 1e-8
#define MOD 1e9+7
#define LL long long
#define ULL unsigned long long     //1844674407370955161
#define INT_INF 0x7f7f7f7f      //2139062143
#define LL_INF 0x7f7f7f7f7f7f7f7f //9187201950435737471
const int dr[]={0, 0, -1, 1, -1, -1, 1, 1};
const int dc[]={-1, 1, 0, 0, -1, 1, -1, 1};
// ios.sync_with_stdio(false);
// 那么cin, 就不能跟C的scanf,sscanf,getchar,fgets之类的一起使用了。
#define N 1000000
bool vis[N+5];
int a[N+5];
bool temp[N+5];
int main()
{
    int T;cin>>T;
    while (T--)
    {
        int n;
        scanf("%d",&n);
        memset(vis,0,sizeof(vis));
        for (int i=1;i<=n;++i)
            scanf("%d",a+i);
        for (int i=1;i<=n;++i)
        {
            for (int j=i+1;j<=n;++j)
            {
                int d=abs(a[i]-a[j]);//记录同余的模,只是记录其中的一部分
                vis[d] = 1;
            }
        }
        bool fd=true;
        for (int m=1;fd;++m)
        {
            if (!vis[m])//表示这个数目前没有同余的
            {
                memset(temp,0,sizeof(temp));
                bool ok=true;
                for (int i = 1;ok&&i<=n;++i)//验证是否真的没有同余
                {
                    if (temp[a[i]%m])
                        ok=false;
                    else
                        temp[a[i]%m]=true;
                }
                if (ok)
                {
                    printf("%d\n",m);
                    fd=false;
                }
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sdau_fangshifeng/article/details/81448770