/*坑爹的奥数(枚举)
口口口+口口口=口口口
将数字1--9分别填到上面的方框中
每个数字只能使用一次
使得等式成立
EG:
173+286=459
就是一种组合
请问一共有多少组合呢?注:173+286=459 与286+173=459是一种组合!
只需枚举每一位即可 就是酱紫^*^*/
# include <stdio.h>
int main(){
int A,B,C,D,E,F,G,H,I,SUM=0;
int X,Y,Z;
for(A=1;A<=9;A++)
for(B=1;B<=9;B++)
for(C=1;C<=9;C++)
for(D=1;D<=9;D++)
for(E=1;E<=9;E++)
for(F=1;F<=9;F++)
for(G=1;G<=9;G++)
for(H=1;H<=9;H++)
for(I=1;I<=9;I++)
if(A!=B&&A!=C&&A!=D&&A!=E&&A!=F&&A!=G&&A!=H&&A!=I
&&B!=C&&B!=D&&B!=E&&B!=F&&B!=G&&B!=H&&B!=I
&&C!=D&&C!=E&&C!=F&&C!=G&&C!=H&&C!=I
&&D!=E&&D!=F&&D!=G&&D!=H&&D!=I
&&E!=F&&E!=G&&E!=H&&E!=I
&&F!=G&&F!=H&&F!=I
&&G!=H&&G!=I
&&H!=I)
{
X=A*100+B*10+C;
Y=D*100+E*10+F;
Z=G*100+H*10+I;
if(X+Y==Z&&X<Y)
{
SUM++;
printf("%d+%d=%d\n",X,Y,Z);
if(X==386)//此处是为了快速跳出循环 得到正确的结果后又加上的
goto AAA;//没有它 时间会>2S
}
}
AAA:printf("SUM=%d",SUM);
return 0;
}
以上是朴素的解法 下面是遍历:
/*用全排列也可以*/
# include <stdio.h>
# define N 11 //几位数
int X,Y,Z,SUM=0;
void DFS(int A[2][N],int step);//A为二维数组 初始化为0 M为A种用的数组长度 step用于递归
int main(){
int A[2][N]={0};//A[0]存放数字 A[1]存放标志
DFS(A,1);
printf("SUM=%d",SUM);
return 0;
}
void DFS(int A[2][N],int step)//递归
{
int i;
if(step==10) //如果前M个已经排好 此时赢直接输出 并停止递归
{
X=A[0][1]*100+A[0][2]*10+A[0][3];
Y=A[0][4]*100+A[0][5]*10+A[0][6];
Z=A[0][7]*100+A[0][8]*10+A[0][9];
if(Z==X+Y&&X<Y)
{
SUM++;
printf("%d+%d=%d\n",X,Y,Z);
}
return; //如果没有return 程序会无休止的循环下去
}
for(i=1;i<10;i++)
{
if(!A[1][i]) //当此前的数字没有在函数中使用
{
A[0][step]=i;
A[1][i]=1;
DFS(A,step+1);
A[1][i]=0;//使用过后记为0
}
}
return;
}
附加小程序:
/*
快速幂运算
模运算:计算除以M的余数 即对M取模
我们将A B除以M后所得的余数相等的情况下 记作A==B(mod M) 规定A(mod M)∈[0,M-1]
基本运算:
假设:A==C(mod M) B==D(mod M)
则:
A+B==C+D (mod M)
A-B==C-D (mod M)
A*B==C*D (mod M)
对于除法:不是所有的除法都成立
当A*C==B*C(mod M)时 (A-B)*C就可以被M整除
当满足 C与M的最大公因数为D时 即D=GYS(C,M)时
(A-B)*(C/D)就可以被M/D整除 又C/D 与M/D的最大公因数为1
所以 A-B可以被M/D整除即 A==B(mod M/GYS(M,C))
快速幂运算
题目:我们把任意的X∈(1,N)都有X^N=X(modN)成立的合数N 叫做Carmichael Number
对于给定的整数N 请判断它是不是Carmichael Number
limit N∈[2,65000]
time<=1S
EG:
输入N= 17 输出 NO
输入N=561 输出 YES
此题目可以用O(sqrt(N))判断是不是质数
有N个待检查数,如果每个数都按照定义O(N)来计算幂 总的时间复杂度为0(N^2) 不能满足时间上的要求
如果 N=2^k
则可以将其表示为 X^N=(((X^2)^2))……
即:N=2^K1 +2^K2 +2^K3+……
就有:
X^N=X^(2^K1) +X^(2^K2) +X^(2^K3)+……
依次求X^(2^i)即可 复杂度O(logN)
根据二进制
EG :22(10)=10110(2)
所以 22=16+4+2 二进制可以快速的求结果
代码:
*/
# include <stdio.h>
typedef __int64 INT;
# define M 10000000
# define MAX 65000
char ZU[MAX+2]={"\0"};//全部初始化为0
INT MI(INT X,INT N,INT mod);//非递归
//INT MID(INT X,INT N,INT mod);//递归与MI功能相同 可以替换上面的MI函数
void AZS(INT N);//埃氏筛法 求出N以内的所有素数 若i是素数则ZU[i]=0
int main(){
INT N,I;
scanf("%I64d",&N);
AZS(MAX);//求出MAX内的所有质数
if(!ZU[N])//如果是质数显然为NO 因为N必须为合数
{
printf("NO\n");
return printf("NO\n");
}
else for(I=2;I<N;I++)//如果N为合数
if(I!=MI(I,N,N))//if(I!=MID(I,N,N))
{
printf("NO");
return 0;
}
printf("YES\n");
return 0;
}
void AZS(INT N)//求出N以内的所有素数
{
int i,j;
for(i=2;i<=N;i++)
if(!ZU[i])
for(j=2*i;j<=N;j+=i)
ZU[j]=1;
}
INT MI(INT X,INT N,INT mod)//非递归
{
INT sum=1;
while(N>0)
{
if(N&1) sum=sum*X%mod; //N&1 即取N的末位
X=X*X%mod;
N>>=1; //N>>=1 即去掉N的二进制末位 也就是 N/=2;
}
return sum;
}
/*INT MID(INT X,INT N,INT mod)//递归
{
INT sum;
if(!N) return 1; //当N位数全部用完 返回1
sum=MID(X*X%mod,N/2,mod);
if(N&1) sum=sum*X%mod;
return sum;
}*/