首先,这题需要负数取模(挺醉人的)
同时,我知道了取模与求余是不同的,http://blog.csdn.net/tedious/article/details/8777994
such as a%b
具体来说,求模运算结果的符号和b一致,求余运算结果的符号和a一致。
正如:
求模运算和求余运算在第一步不同: 取模求余运算在取c的值时,向0 方向舍入(fix()函数);而求余取模运算在计算c的值时,向无穷小方向舍入(floor()函数)。因此,当a和b符号一致时,求模运算和求余运算所得的c的值一致,因此结果一致。但是当符号不一致的时候,结果不一样。
步入正题
<span style="font-family:KaiTi_GB2312;font-size:18px;">#include<cstdio> #include<algorithm> #include<cstdlib> #include<iostream> #include<string> #include<cstring> #include<cmath> using namespace std; typedef long long ll; const int maxn=110; const int prime[]={10007,11261,14843,19997,21893}; ll n,m; ll stack[1001001],tot,a[maxn][5],f[30000][5]; void input(int x)//每个a【x】%prime【j】的余数 { char s[10100]; bool flag=false; scanf("%s",s+1); for (int i=1;s[i];i++)//s[i],这样的用法 ,表示读到'\0'结束啊0 0 { if (s[i]=='-') flag=true; else for (int j=0;j<5;j++) a[x][j]=(a[x][j]*10 /*<=>(a[x][j]<<1)+(a[x][j]<<3)*/ +s[i]-'0')%prime[j];// pay attention to "s[i]-'0'" } if (flag) for (int j=0;j<5;j++) a[x][j]=prime[j]-a[x][j];//负数取模,负数模出来两个余数,一个正余数,一个负余数,负余数加模数==正余数 } ll ff(int x,int j) { ll ret=0; for (int i=n;~i;i--)//为什吗用 ~ ret=(ret*x+a[i][j])%prime[j]; return ret; } int main() { scanf("%lld%lld",&n,&m); for (int i=0;i<=n;i++) input(i); for (int j=0;j<5;j++) for (int i=0;i<prime[j];i++) f[i][j]=ff(i,j);//ans%prime【j】为i的答案是否符合,函数值返回的是方程左边计算值,若为0,就算符合 for (int i=1;i<=m;i++) { int j; for (j=0;j<5;j++) if (f[i%prime[j]][j])break; if (j==5)//学习这种灵活的代码风格,代码能力要加强,学习大神们好的编码思路 stack[++tot]=i; } printf("%d\n",tot); for (int i=1;i<=tot;i++) printf("%d\n",stack[i]); return 0; }</span>