用c语言或者c++,写出行列对角线之和都相等的九宫格,16宫格,

weixin_44953555 2019-04-21 03:00:24
已经写出递归和多线程版本,可是还需要提高速度,求大佬帮忙。
...全文
484 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_44953555 2019-04-21
  • 打赏
  • 举报
回复
引用 2 楼 TxyITxs的回复:
其他的算法,爬山法,A*搜索也可以试试
#include "main.h" int NN, N; int main(int argc, char *argv[]){ int groupSize, totals, i; SQUARE s[MAXNN]; std::thread t[MAXNN];//线程库。 thread指向线程标识符指针。头文件:“thread”它允许向线程函数传递任意数量的参数。 int sumtotalCount, sumpartResultCount, sumresultCount; printf("这是N*N宫格排列,\n"); printf("请输入你想要做的几乘几宫格(在3到5之间),并输入一个数字以作为每一组(多线程的其中一组)的个数: (输入格式要求中间需要为英文的逗号,否则报错)\n "); scanf("%d,%d", &N, &groupSize); NN = N * N; if (N <= 0 || N > 9 || groupSize <= 0 || groupSize > NN) { printf("N的值只能在3到9之间,group size在1在NN之间(NN=N*N)"); return -1; } totals = NN / groupSize;//分成几组来完成,除不尽的当然多增加一组 if (NN % groupSize) totals++; for (i = 0; i < totals; i++) { initSquare(&(s[i]), i * groupSize + 1, std::min(i * groupSize + groupSize, NN));//用他们计算值对的最小值,按照输入的groupsize分组,例如从1到4,从5到8 } for (i = 0; i < totals; i++) { t[i] = std::thread(beginWorker, &(s[i]));//explicit thread(Fm&&fn,Args&&...args);新产生的线程会调用fn函数,该函数的参数由args给出。 } printf("总计搜索: 总计排列完成: 总计发现满足条件个数: 用时:\r\n"); int finished = false; while (!finished) { sumresultCount = 0; sumpartResultCount = 0; sumtotalCount = 0; for (i = 0; i < totals; i++) { finished |= s[i].working; sumresultCount += s[i].resultCount; sumpartResultCount += s[i].partResultCount; sumtotalCount += s[i].totalCount; } finished = !finished; printf("%-16d %-16d %-16d %6.1f\r", sumtotalCount, sumpartResultCount, sumresultCount, (clock() - s[0].t_start) / 1000.0); _sleep(1000);//功能:执行挂起一段时间,也就是等待一段时间在继续执行。 if (_kbhit())//头文件,conio.h,用法#include <stdio.h>,功能:检测按键。 //说明:检测按键是否有键按下,如果有,则返回对应键值;否则,返回零.khbit 不等待键盘按键。无论有无按键都会立即返回。 //在新线程中使用khbit()函数,然后调用API函数SuspenfThread暂停主线程的运行就可以了。 { break; } } printf("\r\n"); char filename[256]; sprintf(filename, "%dx%d result.txt", N, N); fileWrite(filename, s, totals ); for(i=0;i<totals;i++) sl_free(&(s[i].head)); getchar();} void beginWorker(SQUARE *ps){ ps->working = true; ps->t_start = clock(); int i; for (i = ps->scope_start; i <= ps->scope_end; i++) { ps->i[0] = i; ps->remain[i] = 0; ps->rsum[0] = i; ps->csum[0] = i; msquare(ps, 1); ps->remain[i] = 1; } ps->working = false;} void msquare(SQUARE *ps, int no){ int i; int r, c, rsum, csum, tempcsum, temprsum; int xsum1=0,xsum2=0,j; r = no / N; c = no % N; rsum = ps->rsum[r]; csum = ps->csum[c]; //calcThreshold(ps); for (i = 1; i <= NN; i++) { if(i<=N){ xsum1 = ps->i[(N+1)*(i-1)] + xsum1; xsum2 = ps->i[(N+1)*(i)] + xsum2; } if(xsum1 > ps->stdsum || xsum2 > ps->stdsum) break; if (ps->remain[i] == 0) continue; tempcsum = csum + i; temprsum = rsum + i; if (temprsum > ps->stdsum || tempcsum > ps->stdsum) break; if (c == N - 1 && temprsum != ps->stdsum) continue; if (r == N - 1 && tempcsum != ps->stdsum) continue; if ( c > 1 ) { if ((temprsum + ps->threshold_max[c] < ps->stdsum) || temprsum + ps->threshold_min[c] > ps->stdsum) continue; } if (r > 1 ) { if ((tempcsum + ps->threshold_max[r] < ps->stdsum) || tempcsum + ps->threshold_min[r] > ps->stdsum) continue; } ps->totalCount++; ps->i[no] = i; ps->remain[i] = 0; ps->rsum[r] = temprsum; ps->csum[c] = tempcsum; if (no == NN - 1) { ps->partResultCount++; if (exam(ps)) { ps->resultCount++; ps->time = clock() - ps->t_start; sl_append(ps); //print(ps->tail, false); } } else { msquare(ps, no + 1); } ps->remain[i] = 1; ps->i[no] = 0; //calcThreshold(ps); } ps->rsum[r] = rsum; ps->csum[c] = csum;} void initSquare(SQUARE *ps, int start, int end){ int i, temp; memset(ps->i, 0, sizeof(ps->i)); ps->head.next = NULL; ps->tail = &(ps->head); ps->t_start = clock(); ps->resultCount = ps->totalCount = ps->partResultCount = 0; ps->scope_start = start; ps->scope_end = end; temp = 0; for (i = 1; i <= NN; i++) { ps->i[i] = 0; ps->remain[i] = 1; temp += i; } ps->stdsum = temp / N; ps->time = 0; for (i = 0; i < N; i++) { ps->csum[i] = 0; ps->rsum[i] = 0; } calcThreshold(ps);} SQUARENODE *sl_append(SQUARE *ps){ SQUARENODE *newnode; newnode = new SQUARENODE; memcpy(&(newnode->i), ps->i, sizeof(int) * NN + 1); newnode->partResultCount = ps->partResultCount; newnode->time = ps->time; newnode->resultCount = ps->resultCount; newnode->totalCount = ps->totalCount; newnode->next = ps->tail->next; ps->tail->next = newnode; ps->tail = newnode; return newnode;} void sl_free(SQUARENODE *head){ SQUARENODE *node; while (head->next != NULL) { node = head->next; head->next = node->next; delete node; }} void fileWrite(char *filename, SQUARE *ps, int count ){ FILE *fp; SQUARENODE *n; char line[4096], temp[1024]; int i, l, serialnum = 1; fopen_s(&fp, filename, "w"); for (l = 0; l < count; l++) { n = ps[l].head.next; sprintf(line, "\r\nthread %d, scope:%d~%d, ms used:%.3f\r\n", l + 1, ps[l].scope_start, ps[l].scope_end, ps[l].time / 1000.0); fwrite(line, strlen(line), 1, fp); while (n) { sprintf(line, "%6d [ ", serialnum++); for (i = 0; i < NN; i++) { sprintf(temp, "%2d ", n->i[i]); strcat_s(line, sizeof(line), temp); } strcat_s(line, sizeof(line), "] "); sprintf(temp, "%.3f %ld %ld\n", n->time / 1000.0, n->totalCount, n->partResultCount); strcat_s(line, sizeof(line), temp); fwrite(line, strlen(line), 1, fp); n = n->next; } } fclose(fp);} void calcThreshold(SQUARE *ps)//能不能划分情况,分成三种,有的时候只需要大的,有的时候只需要小的,有的时候都需要?{ int temp, i, count;//以16宫格为例,如果前两个数字是16和15,就直接去找最小的可能,可以不用去找最大的。这样行吗? count = N - 1; ps->threshold_max[count] = 0; for (i = 0; i <= NN; i++) { temp = NN - i ; if (ps->remain[temp]==0) continue; ps->threshold_max[count - 1] = temp + ps->threshold_max[count]; if (( N==3 && --count == 1 ) || (N>3 && --count == 2))//改动了一下count的值,排到第二个时,没必要进行检查。九宫格时排到第二个数字开始检查 break; //16宫格以上就从每一列或每一行的第三个数字开始检查 } count = N - 1; ps->threshold_min[count] = 0; for (i = 1; i < NN; i++) { temp = i; if (ps->remain[temp]==0) continue; ps->threshold_min[count - 1] = temp + ps->threshold_min[count]; if (( N==3 && --count == 1 ) || (N>3 && --count == 2)) break; }} int exam(SQUARE *ps){ int j; int sum1, sum2; sum1 = 0; sum2 = 0; for (j = 0; j < N; j++) { sum1 += ps->i[j * N + j]; sum2 += ps->i[j * N + N - 1 - j]; } if (sum1 != ps->stdsum || ps->stdsum != sum2) return 0; else return 1;}
weixin_44953555 2019-04-21
  • 打赏
  • 举报
回复
就是老师要求最终用多线程的版本,让速度更快。遗传法,还有什么爬山算法不会。16宫格现在得需要8,9秒才能出所有结果,代码改进不了了😂
秘境之眼 2019-04-21
  • 打赏
  • 举报
回复
其他的算法,爬山法,A*搜索也可以试试
秘境之眼 2019-04-21
  • 打赏
  • 举报
回复
可以试试遗传算法,看能不能快点

6,129

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 新技术前沿
社区管理员
  • 新技术前沿社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧