noip2014解方程(真不知道那些大神怎么想到取模的,竟然考这个?!)

来源:互联网 发布:开山刀淘宝哪里有卖 编辑:程序博客网 时间:2024/04/30 15:06

首先,这题需要负数取模(挺醉人的)

同时,我知道了取模与求余是不同的,http://blog.csdn.net/tedious/article/details/8777994

such as    a%b

具体来说,求模运算结果的符号和b一致,求余运算结果的符号和a一致。

正如:

求模运算和求余运算在第一步不同: 取模求余运算在取c的值时,向0 方向舍入(fix()函数);而求余取模运算在计算c的值时,向无穷小方向舍入(floor()函数)。因此,当a和b符号一致时,求模运算和求余运算所得的c的值一致,因此结果一致。但是当符号不一致的时候,结果不一样。

步入正题



对于70分的算法,取模,注意要多取几个模数,保证几个模数取完都是0,才算正确!

以下标解

<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>


0 0
原创粉丝点击