您的位置:首页 > 其它

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

2016-04-24 21:09 190 查看
首先,这题需要负数取模(挺醉人的)

同时,我知道了取模与求余是不同的,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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: