解方程 2014NOIP提高组 (数学)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解方程 2014NOIP提高组 (数学)相关的知识,希望对你有一定的参考价值。

解方程

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
 
题目描述 Description

技术分享

输入描述 Input Description

输入文件名为equation.in。

输入共n+2行。

第一行包含2个整数n、m,每两个整数之间用一个空格隔开。

接下来的n+1行每行包含一个整数,依次为a0,a1,a2,……,an。

 

输出描述 Output Description

输出文件名为equation.out。

第一行输出方程在[1, m]内的整数解的个数。

接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。

 

 

样例输入 Sample Input

equation.in

equation.out

2 10

1

-2

1

 

1

1

equation.in

equation.out

2 10

-3

1

 

2

1

2

 

样例输出 Sample Output

equation.in

equation.out

2 10

1

3

2

 

0

数据范围及提示 Data Size & Hint

技术分享

 

/*
将每一项的系数都模一个质数,
若一个数是方程的解,那么在模的意义下它也是方程的解(但反过来不一定)。
为了解决这个“不一定”的问题,多选几个质数,
若一个数在不同模的意义下都是方程的解,那么它有极大的几率就是原方程的解了。
*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>

using namespace std;
const int mod[8]= {0,13,7901,3947,131,6977,22877,49997};
char s[105][1000010];
int n,m;
int num[9][120];

bool solve(int od,int x)
{
    int i,j;
    long long tmp=0;
    long long pw=1;
    for(i=0; i<=n; ++i)
    {
        if(s[i][0]==-) tmp=(tmp-pw*num[od][i])%mod[od];
        else tmp=(tmp+pw*num[od][i])%mod[od];
        pw=pw*x%mod[od];
    }
    while(tmp<0) tmp+=mod[od];
    if(!tmp)return true;
    return false;
}

int res[1000010];
int ans[1000010],act=0;

int main()
{
    int i,j,k;
    scanf("%d%d",&n,&m);
    for(i=0; i<=n; ++i)
        scanf("%s",s[i]);
    int len[101];
    for(i=0; i<=n; ++i)len[i]=strlen(s[i]);
    for(k=1; k<=7; ++k)
        for(i=0; i<=n; ++i)
        {
            for(j=0; j<len[i]; ++j)
            {
                if(s[i][j]==-)continue;
                num[k][i]=num[k][i]*10+s[i][j]-0;
                num[k][i]%=mod[k];
            }
        }
    for(k=1;k<=7;++k)
        for(i=0; i<mod[k] && i<=m; ++i)
        {
            if(!solve(k,i))continue;
            ++res[i];
            for(j=i+mod[k]; j<=m; j+=mod[k])
            {
                res[j]++;
            }
        }
    for(i=1; i<=m; ++i)
        if(res[i]==7)ans[++act]=i;
    printf("%d\n",act);
    for(i=1; i<=act; ++i)printf("%d\n",ans[i]);
    return 0;
}

 

以上是关于解方程 2014NOIP提高组 (数学)的主要内容,如果未能解决你的问题,请参考以下文章

NOIP2014提高组解方程

[NOIP2014] 提高组 洛谷P2312 解方程

Vijos1910 NOIP2014提高组 Day2T3 解方程 其他

[BZOJ3751] [NOIP2014] 解方程 (数学)

[BZOJ3751][NOIP2014]解方程(数学相关+乱搞)

NOIP提高组2012 同余方程