(6.1) horizontal section weighing
1, casual working:
2, ideas to answer: the number of input into a 3-band, since the two can not appear more than the same weight, so the weight can appear only once, 3 hexadecimal representation of representation weight, the symbol represents a different disk
3, the key code
string there (int a, int b) // will be converted to a hexadecimal b, b <10; Returns string objects
{
string str,t;
int q;
while(a>=b)
{
q=a%b;
a=a/b;
str+=q+48;
}
str + = a + 48;
//for(int i=str.size()-1;i>=0;i--)
// t + = str [i]; // no such statement is reversed string obtained
return str;
}
void text (string a) // for band 3, taken there the return value of the parameter
{int b=3;
int t[a.size()+1];
for(int i=0;i<a.size();i++)
{
if(a[i]==2+48)///3
{
t[i]=-1;
if(i<a.size()-1)
a[i+1]+=1;
else
t[i+1]=1;
}
else if(a[i]==48+1) t[i]=1;
else t[i]=0;
if (a [i] == 3) /// need to carry
{
t[i]=0;
if (i <a.size () - 1) // if the last one
a[i+1]+=1;
else
t[i+1]=1;
}
}
for (int i = 0; i <= a.size (); i ++) // into decimal weight
{int b=1;
for(int j=0;j<i;j++)
b*=3;
t[i]*=b;
}
for(int i=a.size();i>=0;i--)//出
{cout<<t[i];
}
}
(6.2) Section Nim game
1, casual working
2, Solution ideas: The number of each pile of stones together by exclusive-OR result is 0, it will acquire the transmission,
Is not 0, then, acquire the exclusive win or A ⊕ B = (¬a ∧ - B) ∨ (A ∧ - ¬b) with 0, 1 iso
3, the key code:
void stops (int a [], int n)
{Int ret = 0;
for(int i=0;i<n;i++)
entitled ^ = A [i];
if(ret==0)
cout << "acquire input" << endl;
else
cout << "acquire win" << endl;
}
(6.3) Section Nim questions Game
1, casual working:
2, Solution idea: to subject to the position of the input piece, the pieces continue to move forward, the final output can not be moved to
In the arrangement of the sequence pieces;
3, the key code:
void stopt (int a [], int n) /// n pawn, a sorted
{Int ret = 0;
if (n & 1 == 1) // odd
{for(int i=0;i<n;i+=2)
ret^=(i==0)?(a[0]-1):(a[i]-a[i-1]-1);
}
else // even number
{for(int i=1;i<n;i+=2)
ret^=(a[i]-a[i-1]-1);
}
if(ret==0)
cout << "first move input" << endl;
else
cout << "first mover win" << endl;
}
(6.4) Section mathematical formula
1, casual working:
(6.5) Section Euclidean algorithm
1, casual working:
(6.6) Section Euclidean algorithm to expand - Bézout's identity
1, casual working:
2, Solution ideas: recursion performed by return after the greatest common divisor, the last determined solution of linear equations.
3, the key code
int x, y; Special Solution Equation // global variable defined xy
int andmax (int a, int b) /// ax + by = m, return ret greatest common divisor
{
if (b == 0) /// recursive boundary, a is the greatest common divisor
{X = 1, y = 0;
return a;
}
int ret=andmax(b,a%b);
//回溯过程计算xy
int x1=x;
x=y;
y=x1-a/b*y;
return ret;
}
///线性方程ax+by=m
//当m为andmax(a,b)的倍数时有解
void lenxy(int a,int b,int m)
{
int d=andmax(a,b);
if(m%d!=0)
{
cout<<"无解";
return ;
}
int t=m/d;//倍数;
x*=t;
y*=t;
}
(6.7)节 欧几里得解“一步之遥”
1、题干:
2、解答思路:F=97,B=-127;得方程:97X+(-127)Y=1;求X与Y的和最小,且x,y大于0
3、关键代码
略
(6.8)节 求解同余方程
1、题干:
(6.9)节 青蛙的约会
1、题干:
2、解答思路:(x+km)%L=(y+kn)%L x+km=L*t2 +P y+kn=L*t1 +P;相减等于
(x-y)+k(m-n)=L(t1+t2) 得: (m-n)*k- L*T =y-x;要求求出K的最小正整数
3、关键代码
int x,y;//定义全局变量xy方程的 特解
int andmax(int a,int b)///ax+by=m, return ret最大公约数
{
if(b==0)///递归边界,a为最大公约数
{x=1;y=0;
return a;
}
int ret=andmax(b,a%b);
//回溯过程计算xy
int x1=x;
x=y;
y=x1-a/b*y;
return ret;
}
///线性方程ax+by=m
//当m为andmax(a,b)的倍数时有解
void lenxy(int a,int b,int m)
{
int d=andmax(a,b);
if(m%d!=0)
{
cout<<"Impossible";
return ;
}
else
{
int t=m/d;//倍数;
x*=t;
b/=d//最简状态下的b
x=(x%b+b)%b;// 得出的x而根据b进行加减得出新值,该式子得出x的最小正整数
cout<<x;
}
}
(6.10)节 模的逆元
1、题干:
2、解答思路:
求(A/B)%9973=? ;已经知道n=A%9973; BX%9973=1;
X为B的模的逆元,即X与1/B之间
所以(A/B)%9973=(X)*A%9973=Xn;
3、关键代码
同上求出X;
(6.11)节 同余方程组
1、题干:
3、关键代码:
int x,y;//定义全局变量xy方程的 特解
int andmax(int a,int b)///ax+by=m, return ret最大公约数
{
if(b==0)///递归边界,a为最大公约数
{x=1;y=0;
return a;
}
int ret=andmax(b,a%b);
//回溯过程计算xy
int x1=x;
x=y;
y=x1-a/b*y;
return ret;
}
///线性方程ax+by=m
//当m为andmax(a,b)的倍数时有解
int minx(int m[],int b[],int lenth)//m为模,b表示余数,m表示数组的个数
{
if(lenth==0&&b[0]==0)
return m[0];
for(int i=1;i<lenth;i++) //前两个式整合成一个新式,与后面不断循环整合,最后成一个
{
int b2_b1=b[i+1]-b[i];
int d=andmax(m[i-1],-m[i]);
int max=m[i]*m[i-1]/d;//求最大公倍数
//现在x的值为前面的y1 m[i-1] *y1+b[i-1]=X
int x0=m[i-1]*x+b[i-1];///x0表示这道式子的最终结果X
x0=(x0%max+max)%max;//X最小正整数
m[i]=x0;
b[i]=max;
//到最后数组a和数组b最后的值存着
}
return m[lenth-1]%b[lenth-1];
}
(6.12)节 素数即质数
1、题干:
2、关键代码:
int ss(int a)
{for(int i=2;i*i<=a;i++)
if(a%i==0)
return i;
return 0;//找不到返回0
}
(6.13)节 素数即质数的筛法
1、题干:求第n个素数
2、解答思路:主要要知道要多大的空间,当数组处理不了那么大的数组时候,可以用string字符串
3、关键代码
#include<iostream>
#include<math.h>
using namespace std;
int ss(int N)
{long n=2;
while(n/log(n)<N) //log是以e为底的
n++;//得出n大小的空间
cout<<n<<endl;
string a;//迫于无奈,使用数组不行
for(int i=0;i<n;i++)
{a+=48;//初始化为0
}
int x=2;
while(x<n)
{
if(a[x]!=48)
{
x++;
continue;
}
int k=2;
while(x*k<n)
{a[x*k]=49;
k++;
}
x++;
}
int sum=0;
for(int i=2;i<n;i++)
{ if(a[i]==48)
sum++;
if(sum==N)
return i;
}
return 0;
}
(6.14)节 快速幂运算
1、题干:求a的n次方
1、循环n次将a个n相乘
int k1(int a,int n)
{int ret=1;
for(int i=0;i<n;i++)
ret*=a;
return ret;
}
2、通过将a=a*a,平方平方的相乘,当下一个平方大于n时,用n-当前平方的个数进行递归,最后返回递归结果。
int k2(int a,int n)
{int ret=1;
int count=1;
int temp=a;
if(n==1)
return a;
while((count<<1)<n)
{
temp*=temp;
count<<=1;
}
ret*=k2(a,n-count);
return ret*temp;
}
3、将n变成2进制,当位上为1时结果才乘上;
int k3(int a,int n)
{int ret=1;
while(n!=0)
{
if((n&1)==1)
ret*=a;
a=a*a;
n>>=1;
}
return ret;
}