问答题

【说明】 著名的四色定理指出任何平面区域图均可用4种颜色着色,使相邻区域着不同的颜色。以下C程序对给定的区域图找出所有可能的不超过4种颜色的着色方案。该程序中用1~4分别表示4种颜色。要着色的N个区域用0~-1编号,区域相邻关系用adj[][]矩阵表示,矩阵的i行j列的元素为1,表示区域i与区域了相邻;矩阵的i行j列的元素为0,表示区域i与区域j不相邻。数组color[]用来存储着色结果,color[i]的值为区域i,所着颜色。 【C程序】 #include <stdio.h> #define N 10 void output(int color[]) { /*输出一种着色方案*/ int i ; for ( i = 0 ; i < N ; i++ ) printf( "%4d" , color[i] ) ; printf ("\n") ; } int back(int *ip ,int color[] ) { /*回溯*/ intc = 4 ; while ( c == 4 ) { if ( *ip <= 0 ) return 0 ; -- (*ip) ; c = (1) ; color[*ip] =-1 ; } return c ; } /*检查区域i,对c种颜色的可用性*/ int colorOk(int i , intc , int [] [N] ,int color[ ] ) { int j ; for (j = 0 ; j < i ; j++ ) if ( (2) ) return 0 ; return 1 ; } /*为区域i选一种可着色的颜色*/ int select (int i ,int c ,int adj [] [N] ,int color[ ] ){ int k ; for(k = c ; k <= 4 ; k++ ) if( colorOK( (3) )) return k ; return 0 ; } int coloring(int adj [] [N]) { /*寻找各种着色方案*/ int color[N] , i , c , cnt ; for(i = 0 ; i < N ; i++) color[i] =-1 ; i = c = 0 ; cnt = 0 ; while(1) { if((c = (4) ) == 0 { c = back( &i , color); if( c == 0 ) return cnt; } else { (5) ; i++ ; if i == N) { output(color); ++cnt ; c = back( &i , color ) ; } else c = 0 ; } } } void main()( int adj[N] [N] = { {0,1,0,1,1,1,1,1,1,1}, {1,0,1,1,0,1,1,1,1,0}, {0,1,0,1,0,1,1,0,1,1}, {1,1,1,0,1,1,0,0,1,1}, {1,0,0,1,0,1,0,0,0,0}, {1,1,1,1,1,0,1,0,0,1}, {1,1,1,0,0,1,0,0,1,0}, {1,1,0,0,0,0,0,0,1,1}, {1,1,1,1,0,0,1,1,0,1}, {1,0,1,1,0,1,0,1,1,0}, } ; printf("共有%d组解.\n",coloring(adj)); }

【参考答案】

(1)color[*ip] (2)adj[i][j]!=0 && color[j]==c (3)I,k,adj,colo......

(↓↓↓ 点击下方‘点击查看答案’看完整答案 ↓↓↓)
热门 试题

问答题
【说明】以下【C程序】的功能是,逐一从指定课程成绩文件中读入学生的考号和成绩,对同一学生汇总他(她)的总成绩,并按如图6-14所示格式输出名次(按总成绩由高到底的顺序)、总成绩、同一名次的学生人数、同一名次学生的学号(按学号由小到大的顺序)。该应用程序约定学生学习课程不超过30种,课程成绩文件的第1个数字就是课程号。统计过程中,同一课程号的成绩文件不能重复输入。该应用程序采用链表结构存储学生的相关信息,链表中的每个表元对应一位学生。在数据输入过程中,形成一个按学号从小到大顺序链接的有序链表。当数据输入结束后,程序按总成绩从高到低,学号从小到大的顺序对链表排序。最后程序按指定格式输出链表中的信息。【C程序】#include<stdio.h>#define M 30#define NLEN 10typedef struct node {int cur_s; * 最近输入成绩的科目* Char no[NLEN];int score;struct node *next;} NODE;int s[M], sp, ss, i, mark, order, C;FILE *fp; NODE *h, *U, *V, *p;Char fname[80], no[NLEN], ans;main(){ for(h = NULL, sp = 0; ;){ printf( 输入科目成绩文件名(输入aaaa表示强行结束)。 n );while(1){ scanf( %s , fname);if (strcmp(fname, aaaa ) == 0)break;if ((fp = fopen(fname, r )) == NULL)printf( 不能打开文件%s, 请重新输入科目文件名。 n , fname);elsebreak;}if (strcmp(fname, aaaa ) == 0) break;fscanf(fp, %d , &ss); * 输入科目号 * s[sp]=s;for (i=0; s[i] ! = ss; 1++);if ( (1) ){ printf( 该科目的成绩已输入,请输入别的科目成绩文件。 n );continue;}sp++;while (fscanf(fp, %s%d , no, &mark) == 2){ * 在链表中寻找最近输入的学号 * for(v = h; v != NULL && strcmp(v-> no, no)<0; u=v, v= v-> next);if (v !=NULL && strcmp(v->no, nb) == 0){ * 该生已有成绩 * if (V->cur_s != ss){ * 该生的当前科目成绩是第一次输入 * v->score += mark; * 累计总成绩 * v->cur_s = ss;} * 同一科目成绩重复输入,后输入成绩被忽略 * }else{ p = (NODE *)malloc(sizeof(NODE)); * 一位新的学生 * strcpy(p->no,no);p->score = mark;p->cur_s = ss;p-> next = v;if ( v == h)(2) ;else(3) ;}}fclose(fp);printf( 还有科目成绩文件要输入吗 (Y N) );scanf( %c , &ans);if (ans == ’N’ || ans == ’n’) break;} * 以下按总成绩和学号对链表排序 * v = (NODE *)malloc(sizeof(NODE));v->next = h;h = v;while (v->next != NULL){ * 在余下的部分链表中找总成绩高学号小的表元 * for(p = v, u = v->next; u->next != NULL; u = u->next)if (u->next->score > p->next->score || u->next->score== p->next->score && strcmp(u->next->no, p->next->no) < 0)p = u;if (p != v){ u = p->next;p->next = (4) ;(5) = v->next;v->next = u;}v = v->next;}v = h; h = h->next; free(v);printf( 名次 总成绩 人数 学号 n ); * 以下按格式要求输出 * v = h; order = 1;while (v != NULL){ for(c = 1, u = v->next; u != NULL && u->score == v->score; (6) ;printf( %4d%7d%8d , order, v->score, c);for (order += c, i = 1; (7) ; v = v->next, i++){ if (i > 1 && i%5 == 1)printf( n%23c , ’ ’);printf( %s , v->no);}printf ( n );}}