user-0 提问: 将1——7的数填入括号不能重复()8()×()=()()()()

回复:
user: user-1
content: 把暴力美学进行到底   #define GETNUM4(num) (((num) % 10000) / 1000) #define GETNUM3(num) (((num) % 1000) / 100) #define GETNUM2(num) (((num) % 100) / 10) #define GETNUM1(num) ((num) % 10) void fun() { 	for (int i = 182; i <= 786; i++)  // 被乘数，三位数，十位是8且数字无重复的 最小三位数182， 最大三位数786 	{ 		for (int j = 1; (GETNUM2(i) == 8) && (j <= 7); j++) // 被乘数第二位必须是8，且 乘数，一位数，1-7 		{ 			int k = i * j; // 乘积 			if	( 					// 乘积，四位数，不包含数字8且数字无重复的 最小四位数1234， 最大四位数7654 					(k >= 1234) && (k <= 7654) &&  					// 总共8个数字是1-8无重复 					((1 << GETNUM3(i)) + (1 << GETNUM2(i)) + (1 << GETNUM1(i)) + (1 << GETNUM1(j)) + (1 << GETNUM4(k)) + (1 << GETNUM3(k)) + (1 << GETNUM2(k)) + (1 << GETNUM1(k))) == 0x1fe 				) 			{ 				printf("%d * %d = %d\n", i, j, k); 			} 		} 	} }

user: user-2
content: 写个全排试一下，不过稍微分析一下就可以加快不少，比如3位数*一位数=四位数，那么三位数的百位肯定不是1，一位数也不能是1，再比如位数还有一些限制，其实还是暴力搜索省脑子

user: user-3
content: 引用 24 楼 DelphiGuy 的回复:呃... 好像不能再短了（这话听起来有点暧昧）  写了几回代码，结果换来这样的一句话，我感觉自己中了圈套

user: user-4
content: 呃... 好像不能再短了（这话听起来有点暧昧）

user: user-4
content: 谁能写个更短的（不要删空行之类的）：   #include <stdio.h>  int x[10][7] = {{1, 4, 5, 7, 2, 3, 6}, {1, 3, 5, 6, 2, 7, 4}, {1, 4, 5, 7, 3, 2, 6},   {1, 5, 6, 7, 3, 4, 2}, {2, 4, 5, 6, 3, 7, 1}, {1, 5, 6, 7, 4, 3, 2}, {1, 3, 4, 5, 6, 7, 2},    {1, 3, 5, 6, 7, 2, 4}, {2, 4, 5, 6, 7, 3, 1}, {1, 3, 4, 5, 7, 6, 2}}, y[24][4] = {{0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 1, 3}, {0, 2, 3, 1}, {0, 3, 1, 2}, {0, 3, 2, 1},   {1, 0, 2, 3}, {1, 0, 3, 2}, {1, 2, 0, 3}, {1, 2, 3, 0}, {1, 3, 0, 2}, {1, 3, 2, 0},   {2, 0, 1, 3}, {2, 0, 3, 1}, {2, 1, 0, 3}, {2, 1, 3, 0}, {2, 3, 0, 1}, {2, 3, 1, 0},   {3, 0, 1, 2}, {3, 0, 2, 1}, {3, 1, 0, 2}, {3, 1, 2, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}}, i, j;  int main() {   for (i = 0; i < 10; i++)     for (j = 0; j < 24; j++)       if ((x[i][y[j][0]] * 100 + 80 + x[i][4]) * x[i][5] == x[i][y[j][1]] * 1000 + x[i][y[j][2]] * 100 + x[i][y[j][3]] * 10 + x[i][6])         printf("%d8%d * %d = %d%d%d%d\n", x[i][y[j][0]], x[i][4], x[i][5], x[i][y[j][1]], x[i][y[j][2]], x[i][y[j][3]], x[i][6]);    return 0; }

user: user-3
content: 引用 10 楼 bluestar2009 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 闲着也是闲着！//将1到7的数填入括号不能重复()8()×()=()()()() #include <stdio.h> #include <string.h> int next_pl(char * f, char * l) {     char t;     char *ff,*ll;      char * i = l;     if (f == l || f == --i) return (0);     while (1) {         char * p = i;         if (*--i < *p) {             char * j = l;             while (1) {                 j--;                 if (*i<*j) break;//             }             t=*i;*i=*j;*j=t;             ff=p;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (1);         }         if (i == f) {             ff=f;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (0);         }     } } int main() {     char a[]="\x01\x02\x03\x04\x05\x06\x07";      do {         if ((a[0]*100+80+a[1])*a[2]==a[3]*1000+a[4]*100+a[5]*10+a[6])             printf("%d8%d*%d=%d%d%d%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]);     } while (next_pl(a,a+7));     return 0; } //582*3=1746 //  高人！！我写了53行···[/quote] 楼主想要短的？ 那试试这个咯 #include <stdio.h> void _swap(char *l, char *r){ char t = *l; *l = *r; *r = t; } void fun(char* arr, char* end, char *cur) {     if (cur == end){         if ((arr[0] * 100 + 80 + arr[1])*arr[2] == arr[3] * 1000 + arr[4] * 100 + arr[5] * 10 + arr[6])             printf("%d8%d*%d=%d%d%d%d\n", arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6]);         return;     }     for (char *sw = cur; sw != end; sw++){         _swap(cur, sw);         fun(arr,end,cur+1);         _swap(cur, sw);     } } int main() {     char a[7] = { 1, 2, 3, 4, 5, 6, 7 };     fun(a, a + 7, a);     return 0; }

user: user-3
content: 引用 21 楼 DelphiGuy 的回复:那个很厚道，而且是优化算法，利用个位数的乘机关系把搜索次数从720降到240。 不过受你的启发，我又写了一个更短的，效率肯定不如#19的代码，但是比#20的要好很多：  #include <stdio.h>  int main() {   int x[10][3] = {{2,3,6},{2,7,4},{3,2,6},{3,4,2},{3,7,1},{4,3,2},{6,7,2},{7,2,4},{7,3,1},{7,6,2}}, y[10];   for (y[4] = 0, y[7] = (1 << x[y[4]][0]) + (1 << x[y[4]][1]) + (1 << x[y[4]][2]); y[4] < 10; y[4]++)     for (y[5] = 1234; y[5] < 7655; y[5]++) {       for (y[6] = 0, y[8] = y[5], y[9] = y[7]; y[6] < 4; y[6]++) {y[y[6]] = y[8] % 10; y[8] /= 10; y[9] += 1 << y[y[6]];}       if (y[9] == 254 && (y[0] * 100 + 80 + x[y[4]][0]) * x[y[4]][1] == y[1] * 1000 + y[2] * 100 + y[3] * 10 + x[y[4]][2])         printf("%d8%d * %d = %d%d%d%d\n", y[0], x[y[4]][0], x[y[4]][1], y[1], y[2], y[3], x[y[4]][2]);     }   return 0; }  从优化效率来说，你这个确实厚道 但是如果是以短为目标，hardcode一个4！的全排列就显得太鸡贼了，不正派哇  还有，请不要跟20楼比效率，20楼本来就没考虑效率，这等于跟秃子比头发多，这么计较纯粹拉低你自己的档次。。。  受你启发，我又写了个更短的，不要跟我比效率，我直接认输。。 #include <stdio.h>  int main() {     for (int v = 1234567; v <= 7654321; v++){                for (int f[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, vl = v; (f[vl % 10] = 1), vl; vl /= 10)             if (vl<10 && f[1] + f[2] + f[3] + f[4] + f[5] + f[6] + f[7] == 7 && ((v / 1000000) * 100 + 80 + ((v / 100000) % 10)) * ((v / 10000) % 10) == v % 10000)                 printf("%d8%d * %d = %d\n", v / 1000000, (v / 100000) % 10, (v / 10000) % 10, v % 10000);     }     return 0; }

user: user-0
content: 引用 17 楼 mstlq 的回复:[quote=引用 10 楼 bluestar2009 的回复:] [quote=引用 8 楼 zhao4zhong1 的回复:] 闲着也是闲着！//将1到7的数填入括号不能重复()8()×()=()()()() #include <stdio.h> #include <string.h> int next_pl(char * f, char * l) {     char t;     char *ff,*ll;      char * i = l;     if (f == l || f == --i) return (0);     while (1) {         char * p = i;         if (*--i < *p) {             char * j = l;             while (1) {                 j--;                 if (*i<*j) break;//             }             t=*i;*i=*j;*j=t;             ff=p;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (1);         }         if (i == f) {             ff=f;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (0);         }     } } int main() {     char a[]="\x01\x02\x03\x04\x05\x06\x07";      do {         if ((a[0]*100+80+a[1])*a[2]==a[3]*1000+a[4]*100+a[5]*10+a[6])             printf("%d8%d*%d=%d%d%d%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]);     } while (next_pl(a,a+7));     return 0; } //582*3=1746 //  高人！！我写了53行···[/quote] 楼主想要短的？ 那试试这个咯 #include <stdio.h> void _swap(char *l, char *r){ char t = *l; *l = *r; *r = t; } void fun(char* arr, char* end, char *cur) {     if (cur == end){         if ((arr[0] * 100 + 80 + arr[1])*arr[2] == arr[3] * 1000 + arr[4] * 100 + arr[5] * 10 + arr[6])             printf("%d8%d*%d=%d%d%d%d\n", arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6]);         return;     }     for (char *sw = cur; sw != end; sw++){         _swap(cur, sw);         fun(arr,end,cur+1);         _swap(cur, sw);     } } int main() {     char a[7] = { 1, 2, 3, 4, 5, 6, 7 };     fun(a, a + 7, a);     return 0; }[/quote] 高人啊 递归一直不怎么明白

user: user-4
content: 乘机关系 -> 乘积关系

user: user-4
content: 那个很厚道，而且是优化算法，利用个位数的乘机关系把搜索次数从720降到240。 不过受你的启发，我又写了一个更短的，效率肯定不如#19的代码，但是比#20的要好很多：  #include <stdio.h>  int main() {   int x[10][3] = {{2,3,6},{2,7,4},{3,2,6},{3,4,2},{3,7,1},{4,3,2},{6,7,2},{7,2,4},{7,3,1},{7,6,2}}, y[10];   for (y[4] = 0, y[7] = (1 << x[y[4]][0]) + (1 << x[y[4]][1]) + (1 << x[y[4]][2]); y[4] < 10; y[4]++)     for (y[5] = 1234; y[5] < 7655; y[5]++) {       for (y[6] = 0, y[8] = y[5], y[9] = y[7]; y[6] < 4; y[6]++) {y[y[6]] = y[8] % 10; y[8] /= 10; y[9] += 1 << y[y[6]];}       if (y[9] == 254 && (y[0] * 100 + 80 + x[y[4]][0]) * x[y[4]][1] == y[1] * 1000 + y[2] * 100 + y[3] * 10 + x[y[4]][2])         printf("%d8%d * %d = %d%d%d%d\n", y[0], x[y[4]][0], x[y[4]][1], y[1], y[2], y[3], x[y[4]][2]);     }   return 0; }

user: user-3
content: 引用 19 楼 DelphiGuy 的回复:谁能写个更短的（不要删空行之类的）：   #include <stdio.h>  int x[10][7] = {{1, 4, 5, 7, 2, 3, 6}, {1, 3, 5, 6, 2, 7, 4}, {1, 4, 5, 7, 3, 2, 6},   {1, 5, 6, 7, 3, 4, 2}, {2, 4, 5, 6, 3, 7, 1}, {1, 5, 6, 7, 4, 3, 2}, {1, 3, 4, 5, 6, 7, 2},    {1, 3, 5, 6, 7, 2, 4}, {2, 4, 5, 6, 7, 3, 1}, {1, 3, 4, 5, 7, 6, 2}}, y[24][4] = {{0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 1, 3}, {0, 2, 3, 1}, {0, 3, 1, 2}, {0, 3, 2, 1},   {1, 0, 2, 3}, {1, 0, 3, 2}, {1, 2, 0, 3}, {1, 2, 3, 0}, {1, 3, 0, 2}, {1, 3, 2, 0},   {2, 0, 1, 3}, {2, 0, 3, 1}, {2, 1, 0, 3}, {2, 1, 3, 0}, {2, 3, 0, 1}, {2, 3, 1, 0},   {3, 0, 1, 2}, {3, 0, 2, 1}, {3, 1, 0, 2}, {3, 1, 2, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}}, i, j;  int main() {   for (i = 0; i < 10; i++)     for (j = 0; j < 24; j++)       if ((x[i][y[j][0]] * 100 + 80 + x[i][4]) * x[i][5] == x[i][y[j][1]] * 1000 + x[i][y[j][2]] * 100 + x[i][y[j][3]] * 10 + x[i][6])         printf("%d8%d * %d = %d%d%d%d\n", x[i][y[j][0]], x[i][4], x[i][5], x[i][y[j][1]], x[i][y[j][2]], x[i][y[j][3]], x[i][6]);    return 0; }   这么打表不大厚道嘛。。。 我还可以直接hack一下  #include <stdio.h>  int main() {     printf("582*3=1746\n");     return 0; }  如果不求效率，只要短，也可以这样 #include <stdio.h>  int main() {     for (int v = 1234567; v <= 7654321; v++){         int f[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };         for (int vl = v; vl; vl /= 10)             f[vl % 10] = 1;         if (f[1] + f[2] + f[3] + f[4] + f[5] + f[6] + f[7] == 7 && ((v / 1000000) * 100 + 80 + ((v / 100000) % 10)) * ((v / 10000) % 10) == v % 10000)             printf("%d8%d * %d = %d\n", v / 1000000, (v / 100000) % 10, (v / 10000) % 10, v % 10000);     }     return 0; }

user: user-5
content: zhao4zhong1一般不生产代码，他只是代码的搬运工。

user: user-5
content: zhao4zhong1一旦不复制粘贴，一般都是精品。

user: user-6
content: 引用 9 楼 zhao4zhong1 的回复://全排列的生成算法 //  全排列的生成算法就是对于给定的字符集，用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。任何n个字符集的排列都可以与1～n的n个数字的排列一一对应， //  因此在此就以n个数字的排列为例说明排列的生成法。 //  n个字符的全体排列之间存在一个确定的线性顺序关系。所有的排列中除最后一个排列外，都有一个后继；除第一个排列外，都有一个前驱。每个排列的后继都可以从 //  它的前驱经过最少的变化而得到，全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。 //  全排列的生成法通常有以下几种： //  字典序法 //  递增进位数制法 //  递减进位数制法 //  邻位交换法 //  递归类算法 //1.字典序法 效率高且顺序自然 //  字典序法中，对于数字1、2、3......n的排列，不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列12354和12345，排列12345在前， //  排列12354在后。按照这样的规定，5个数字的所有的排列中最前面的是12345，最后面的是54321。 //  字典序算法如下： //  设P是1～n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn //  1）从排列的右端开始，找出第一个比右边数字小的数字的序号j（j从左端开始计算），即 j=max{i|pi<pi+1} //  2）在pj的右边的数字中，找出所有比pj大的数中最小的数字pk，即 k=max{i|pi>pj}（右边的数从右至左是递增的，因此k是所有大于pj的数字中序号最大者） //  3）对换pi，pk //  4）再将pj+1......pk-1pkpk+1pn倒转得到排列p’’=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1，这就是排列p的下一个下一个排列。 //  例如839647521是数字1～9的一个排列。从它生成下一个排列的步骤如下： //  自右至左找出排列中第一个比右边数字小的数字4 839647521 //  在该数字后的数字中找出比4大的数中最小的一个5 839647521 //  将5与4交换 839657421 //  将7421倒转 839651247 //  所以839647521的下一个排列是839651247。 //2.递增进位数制法 //  在递增进位制数法中，从一个排列求另一个排列需要用到中介数。如果用 ki表示排列p1p2...pi...pn中元素pi的右边比pi小的数的个数，则排列的中介数就是对应的 //  排列k1 ...... ki...... kn-1。 //  例如排列839647521的中介数是72642321，7、2、6、......分别是排列中数字8、3、9、......的右边比它小的数字个数。 //  中介数是计算排列的中间环节。已知一个排列，要求下一个排列，首先确定其中介数，一个排列的后继，其中介数是原排列中介数加1，需要注意的是，如果中介数的 //  末位kn-1+1=2，则要向前进位，一般情形，如果ki+1=n-i+1，则要进位，这就是所谓的递增进位制。例如排列839647521的中介数是72642321，则下一个排列的中介数 //  是67342221+1=67342300（因为1+1=2，所以向前进位，2+1=3，又发生进位，所以下一个中介数是67342300）。 //  得到中介数后，可根据它还原对应得排列。 //  算法如下： //  中介数k1、k2、......、kn-1的各位数字顺序表示排列中的数字n、n-1、......、2在排列中距右端的的空位数，因此，要按k1、k2、......、kn-1的值从右向左 //  确定n、n-1、......、2的位置，并逐个放置在排列中：i放在右起的ki+1位，如果某位已放有数字，则该位置不算在内，最后一个空位放1。 //  因此从67342300可得到排列849617523，它就是839647521的后一个排列。因为9最先放置，k1=6，9放在右起第7位，空出6个空位，然后是放8，k2=7，8放在右起第8位， //  但9占用一位，故8应放在右起第9位，余类推。 //3.递减进位制数法 //  在递增进位制数法中，中介数的最低位是逢2进1，进位频繁，这是一个缺点。把递增进位制数翻转,就得到递减进位制数。 //  839647521的中介数是67342221(k1k2...kn-1)，倒转成为12224376(kn-1...k2k1)，这是递减进位制数的中介数：ki(i=n-1,n-2,...,2)位逢i向ki-1位进1。给定排列p， //  p的下一个排列的中介数定义为p的中介数加1。例如p=839647521，p的中介数为12224376，p的下一个排列的中介数为12224376+1=12224377，由此得到p的下一个 //  排列为893647521。 //  给定中介数，可用与递增进位制数法类似的方法还原出排列。但在递减进位制数中，可以不先计算中介数就直接从一个排列求出下一个排列。具体算法如下： //  1）如果p(i)=n且i<>n，则p(i)与p(i-1)交换 //  2）如果p(n)=n，则找出一个连续递减序列9、8、......、i，将其从排列左端删除，再以相反顺序加在排列右端，然后将i-1与左边的数字交换 //  例如p=893647521的下一个排列是983647521。求983647521的下一个排列时，因为9在最左边且第2位为8，第3位不是7，所以将8和9从小到大排于最右端364752189， //  再将7与其左方数字对调得到983647521的下一个排列是367452189。又例如求987635421的下一个排列，只需要将9876从小到大排到最右端并将5与其左方数字3对调， //  得到534216789。 //4.邻位对换法 效率最高但顺序不自然 //  邻位对换法中下一个排列总是上一个排列某相邻两位对换得到的。以4个元素的排列为例，将最后的元素4逐次与前面的元素交换，可以生成4个新排列： //  1 2 3 4, 1 2 4 3, 1 4 2 3, 4 1 2 3 //  然后将最后一个排列的末尾的两个元素交换，再逐次将排头的4与其后的元素交换，又生成四个新排列： //  4 1 3 2, 1 4 3 2, 1 3 4 2, 1 3 2 4 //  再将最后一个排列的开头的两个元素交换，将4从后往前移： //  3 1 2 4, 3 1 4 2, 3 4 1 2, 4 3 1 2 //  如此循环4!次既可求出全部排列。 //5.元素增值法（n进制法）效率低 //  1）从原始排列p=p1p2......pn开始，第n位加n-1，如果该位的值超过n，则将它除以n，用余数取代该位，并进位（将第n-1位加1） //  2）再按同样方法处理n-1位，n-2位，......，直至不再发生进位为止，处理完一个排列就产生了一个新的排列 //  3）将其中有相同元素的排列去掉 //  4）当第一个元素的值>n则结束 //  以3个数1、2、3的排列为例：原始排列是1 2 3，从它开始，第3个元素是3，3+2=5，5 Mod 3=2，第2个元素是2，2+1=3，所以新排列是1 3 2。通过元素增值，顺序产生的 //  排列是：1 2 3，1 3 2，2 1 1，2 1 3，2 2 2，2 3 1，2 3 3，3 1 2，3 2 1 //  有下划线的排列中存在重复元素，丢弃，余下的就是全部排列。 //6.递归类算法 //  全排列的生成方法用递归方式描述比较简洁，实现的方法也有多种。 //  1）回溯法 //  回溯法通常是构造一颗生成树。以3个元素为例；树的节点有个数据，可取值是1、2、3。如果某个为0，则表示尚未取值。 //  初始状态是(0，0，0)，第1个元素值可以分别挑选1，2，3，因此扩展出3个子结点。用相同方法找出这些结点的第2个元素的可能值，如此反复进行，一旦出现新结点的3个 //  数据全非零，那就找到了一种全排列方案。当尝试了所有可能方案，即获得了问题的解答。 //  2）递归算法 //  如果用P表示n个元素的排列，而Pi表示不包含元素i的排列，(i)Pi表示在排列Pi前加上前缀i的排列，那么，n个元素的排列可递归定义为： //  如果n=1，则排列P只有一个元素i //  如果n>1，则排列P由排列(i)Pi构成（i=1、2、....、n-1）。 //  根据定义，容易看出如果已经生成了k-1个元素的排列，那么，k个元素的排列可以在每个k-1个元素的排列Pi前添加元素i而生成。例如2个元素的排列是1 2和2 1，对与个 //  元素而言，p1是2 3和3 2，在每个排列前加上1即生成1 2 3和1 3 2两个新排列，p2和p3则是1 3、3 1和1 2、2 1，按同样方法可生成新排列2 1 3、2 3 1和3 1 2、3 2 1。 //  3）循环移位法 //  如果已经生成了k-1个元素的排列，则在每个排列后添加元素k使之成为k个元素的排列，然后将每个排列循环左移（右移），每移动一次就产生一个新的排列。 //  例如2个元素的排列是1 2和2 1。在1 2 后加上3成为新排列1 2 3，将它循环左移可再生成新排列2 3 1、3 1 2，同样2 1 可生成新排列2 1 3、1 3 2和3 2 1。 他们都说赵四老师是个大水比，我感觉好屌

user: user-0
content: 我是用字符串处理的··  贴一下我的拙劣代码 #include <stdio.h> #include <stdlib.h> #include <string.h>  int main() { 	int aa[9] ={0}; 	int i=0,j=0,k=0,m=0,flag=0,cs=0,bcs=0,len=0; 	char res[5]= {0},ccs[4]={0},cbcs[2]={0},total[9]={0}; 	for (i=1;i<8;i++) 	{ 		for (j=1;j<8;j++) 		{ 			for (k=1;k<8;k++) 			{ 				cs = (i*100) + 80 + j; 				bcs = k; 				itoa(cs*bcs,res,10); 				if (strlen(res)!=4) 				{ 					continue; 				} 				itoa(cs,ccs,10); 				itoa(bcs,cbcs,10); 				strcpy(total,ccs); 				strcat(total,cbcs); 				strcat(total,res); 				len = strlen(total); 				if (len==8) 				{ 					memset(&aa,0,sizeof(int)*9); 					for (m=0;m<len;m++) 					{ 						aa[total[m]-48]++; 					} 					flag = 0; 					for (m=1;m<9;m++) 					{ 						if (aa[m]!=1) 						{ 							flag = 1; 							break; 						} 					} 					if (flag!=1) 					{ 						printf("cs[%d]bcs[%d]res[%d]\n",cs,bcs,cs*bcs); 						return 0; 					} 				} 			} 		} 	} }

user: user-5
content: 开来→看来

user: user-5
content: 引用 2 楼 mstlq 的回复:最无脑就是写个全排列，每个排列验证一下是否符合条件 开来我比无脑还无脑！连全排列都懒得写。 无脑非无脑，何处惹尘埃。

user: user-3
content: 引用 8 楼 zhao4zhong1 的回复:闲着也是闲着！//将1到7的数填入括号不能重复()8()×()=()()()() #include <stdio.h> #include <string.h> int next_pl(char * f, char * l) {     char t;     char *ff,*ll;      char * i = l;     if (f == l || f == --i) return (0);     while (1) {         char * p = i;         if (*--i < *p) {             char * j = l;             while (1) {                 j--;                 if (*i<*j) break;//             }             t=*i;*i=*j;*j=t;             ff=p;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (1);         }         if (i == f) {             ff=f;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (0);         }     } } int main() {     char a[]="\x01\x02\x03\x04\x05\x06\x07";      do {         if ((a[0]*100+80+a[1])*a[2]==a[3]*1000+a[4]*100+a[5]*10+a[6])             printf("%d8%d*%d=%d%d%d%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]);     } while (next_pl(a,a+7));     return 0; } //582*3=1746 //  难得呀，这回居然不是复制粘贴

user: user-0
content: 引用 8 楼 zhao4zhong1 的回复:闲着也是闲着！//将1到7的数填入括号不能重复()8()×()=()()()() #include <stdio.h> #include <string.h> int next_pl(char * f, char * l) {     char t;     char *ff,*ll;      char * i = l;     if (f == l || f == --i) return (0);     while (1) {         char * p = i;         if (*--i < *p) {             char * j = l;             while (1) {                 j--;                 if (*i<*j) break;//             }             t=*i;*i=*j;*j=t;             ff=p;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (1);         }         if (i == f) {             ff=f;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (0);         }     } } int main() {     char a[]="\x01\x02\x03\x04\x05\x06\x07";      do {         if ((a[0]*100+80+a[1])*a[2]==a[3]*1000+a[4]*100+a[5]*10+a[6])             printf("%d8%d*%d=%d%d%d%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]);     } while (next_pl(a,a+7));     return 0; } //582*3=1746 //  高人！！我写了53行···

user: user-5
content: //全排列的生成算法 //  全排列的生成算法就是对于给定的字符集，用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。任何n个字符集的排列都可以与1～n的n个数字的排列一一对应， //  因此在此就以n个数字的排列为例说明排列的生成法。 //  n个字符的全体排列之间存在一个确定的线性顺序关系。所有的排列中除最后一个排列外，都有一个后继；除第一个排列外，都有一个前驱。每个排列的后继都可以从 //  它的前驱经过最少的变化而得到，全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。 //  全排列的生成法通常有以下几种： //  字典序法 //  递增进位数制法 //  递减进位数制法 //  邻位交换法 //  递归类算法 //1.字典序法 效率高且顺序自然 //  字典序法中，对于数字1、2、3......n的排列，不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列12354和12345，排列12345在前， //  排列12354在后。按照这样的规定，5个数字的所有的排列中最前面的是12345，最后面的是54321。 //  字典序算法如下： //  设P是1～n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn //  1）从排列的右端开始，找出第一个比右边数字小的数字的序号j（j从左端开始计算），即 j=max{i|pi<pi+1} //  2）在pj的右边的数字中，找出所有比pj大的数中最小的数字pk，即 k=max{i|pi>pj}（右边的数从右至左是递增的，因此k是所有大于pj的数字中序号最大者） //  3）对换pi，pk //  4）再将pj+1......pk-1pkpk+1pn倒转得到排列p’’=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1，这就是排列p的下一个下一个排列。 //  例如839647521是数字1～9的一个排列。从它生成下一个排列的步骤如下： //  自右至左找出排列中第一个比右边数字小的数字4 839647521 //  在该数字后的数字中找出比4大的数中最小的一个5 839647521 //  将5与4交换 839657421 //  将7421倒转 839651247 //  所以839647521的下一个排列是839651247。 //2.递增进位数制法 //  在递增进位制数法中，从一个排列求另一个排列需要用到中介数。如果用 ki表示排列p1p2...pi...pn中元素pi的右边比pi小的数的个数，则排列的中介数就是对应的 //  排列k1 ...... ki...... kn-1。 //  例如排列839647521的中介数是72642321，7、2、6、......分别是排列中数字8、3、9、......的右边比它小的数字个数。 //  中介数是计算排列的中间环节。已知一个排列，要求下一个排列，首先确定其中介数，一个排列的后继，其中介数是原排列中介数加1，需要注意的是，如果中介数的 //  末位kn-1+1=2，则要向前进位，一般情形，如果ki+1=n-i+1，则要进位，这就是所谓的递增进位制。例如排列839647521的中介数是72642321，则下一个排列的中介数 //  是67342221+1=67342300（因为1+1=2，所以向前进位，2+1=3，又发生进位，所以下一个中介数是67342300）。 //  得到中介数后，可根据它还原对应得排列。 //  算法如下： //  中介数k1、k2、......、kn-1的各位数字顺序表示排列中的数字n、n-1、......、2在排列中距右端的的空位数，因此，要按k1、k2、......、kn-1的值从右向左 //  确定n、n-1、......、2的位置，并逐个放置在排列中：i放在右起的ki+1位，如果某位已放有数字，则该位置不算在内，最后一个空位放1。 //  因此从67342300可得到排列849617523，它就是839647521的后一个排列。因为9最先放置，k1=6，9放在右起第7位，空出6个空位，然后是放8，k2=7，8放在右起第8位， //  但9占用一位，故8应放在右起第9位，余类推。 //3.递减进位制数法 //  在递增进位制数法中，中介数的最低位是逢2进1，进位频繁，这是一个缺点。把递增进位制数翻转,就得到递减进位制数。 //  839647521的中介数是67342221(k1k2...kn-1)，倒转成为12224376(kn-1...k2k1)，这是递减进位制数的中介数：ki(i=n-1,n-2,...,2)位逢i向ki-1位进1。给定排列p， //  p的下一个排列的中介数定义为p的中介数加1。例如p=839647521，p的中介数为12224376，p的下一个排列的中介数为12224376+1=12224377，由此得到p的下一个 //  排列为893647521。 //  给定中介数，可用与递增进位制数法类似的方法还原出排列。但在递减进位制数中，可以不先计算中介数就直接从一个排列求出下一个排列。具体算法如下： //  1）如果p(i)=n且i<>n，则p(i)与p(i-1)交换 //  2）如果p(n)=n，则找出一个连续递减序列9、8、......、i，将其从排列左端删除，再以相反顺序加在排列右端，然后将i-1与左边的数字交换 //  例如p=893647521的下一个排列是983647521。求983647521的下一个排列时，因为9在最左边且第2位为8，第3位不是7，所以将8和9从小到大排于最右端364752189， //  再将7与其左方数字对调得到983647521的下一个排列是367452189。又例如求987635421的下一个排列，只需要将9876从小到大排到最右端并将5与其左方数字3对调， //  得到534216789。 //4.邻位对换法 效率最高但顺序不自然 //  邻位对换法中下一个排列总是上一个排列某相邻两位对换得到的。以4个元素的排列为例，将最后的元素4逐次与前面的元素交换，可以生成4个新排列： //  1 2 3 4, 1 2 4 3, 1 4 2 3, 4 1 2 3 //  然后将最后一个排列的末尾的两个元素交换，再逐次将排头的4与其后的元素交换，又生成四个新排列： //  4 1 3 2, 1 4 3 2, 1 3 4 2, 1 3 2 4 //  再将最后一个排列的开头的两个元素交换，将4从后往前移： //  3 1 2 4, 3 1 4 2, 3 4 1 2, 4 3 1 2 //  如此循环4!次既可求出全部排列。 //5.元素增值法（n进制法）效率低 //  1）从原始排列p=p1p2......pn开始，第n位加n-1，如果该位的值超过n，则将它除以n，用余数取代该位，并进位（将第n-1位加1） //  2）再按同样方法处理n-1位，n-2位，......，直至不再发生进位为止，处理完一个排列就产生了一个新的排列 //  3）将其中有相同元素的排列去掉 //  4）当第一个元素的值>n则结束 //  以3个数1、2、3的排列为例：原始排列是1 2 3，从它开始，第3个元素是3，3+2=5，5 Mod 3=2，第2个元素是2，2+1=3，所以新排列是1 3 2。通过元素增值，顺序产生的 //  排列是：1 2 3，1 3 2，2 1 1，2 1 3，2 2 2，2 3 1，2 3 3，3 1 2，3 2 1 //  有下划线的排列中存在重复元素，丢弃，余下的就是全部排列。 //6.递归类算法 //  全排列的生成方法用递归方式描述比较简洁，实现的方法也有多种。 //  1）回溯法 //  回溯法通常是构造一颗生成树。以3个元素为例；树的节点有个数据，可取值是1、2、3。如果某个为0，则表示尚未取值。 //  初始状态是(0，0，0)，第1个元素值可以分别挑选1，2，3，因此扩展出3个子结点。用相同方法找出这些结点的第2个元素的可能值，如此反复进行，一旦出现新结点的3个 //  数据全非零，那就找到了一种全排列方案。当尝试了所有可能方案，即获得了问题的解答。 //  2）递归算法 //  如果用P表示n个元素的排列，而Pi表示不包含元素i的排列，(i)Pi表示在排列Pi前加上前缀i的排列，那么，n个元素的排列可递归定义为： //  如果n=1，则排列P只有一个元素i //  如果n>1，则排列P由排列(i)Pi构成（i=1、2、....、n-1）。 //  根据定义，容易看出如果已经生成了k-1个元素的排列，那么，k个元素的排列可以在每个k-1个元素的排列Pi前添加元素i而生成。例如2个元素的排列是1 2和2 1，对与个 //  元素而言，p1是2 3和3 2，在每个排列前加上1即生成1 2 3和1 3 2两个新排列，p2和p3则是1 3、3 1和1 2、2 1，按同样方法可生成新排列2 1 3、2 3 1和3 1 2、3 2 1。 //  3）循环移位法 //  如果已经生成了k-1个元素的排列，则在每个排列后添加元素k使之成为k个元素的排列，然后将每个排列循环左移（右移），每移动一次就产生一个新的排列。 //  例如2个元素的排列是1 2和2 1。在1 2 后加上3成为新排列1 2 3，将它循环左移可再生成新排列2 3 1、3 1 2，同样2 1 可生成新排列2 1 3、1 3 2和3 2 1。