运动会分数

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
#include <math.h>
#include <process.h>
#include <stdio.h>

#define N 20 //学校最大数目
#define M 20 //男子项目最大数
#define W 20 //女子项目最大数

//存放项目信息的结构体
typedef struct
{
    int inum;     //项目编号
    int top;      //取名次的数目
    int range[5]; //名次
    int mark[5];  //分数
} itemnode;

//存放学校信息的结构体
typedef struct
{
    int snum;          //学校编号
    int score;         //学校总分
    int mscore;        //男子总分
    int wscore;        //女子总分
    itemnode t[M + W]; //项目数组
} snode;
snode a[N]; //定义一个学校数组

//菜单函数
void menu(int n, int m, int w)
{ //n代表学校数,m代表男子数,w代表女子数
    int c;
    void input(int n, int m, int w);   //输入功能
    void output(int n, int m, int w);  //输入功能
    void sortput(int n, int m, int w); //排序输出
    void search(int n, int m, int w);  //查询功能
    printf("\t\t\t欢迎使用\t\t\t\t\t\n");
    printf("华信运动会分数统计系统\n\n");
    printf("1.信息输入\n");
    printf("2.统计输出\n");
    printf("3.排序输出\n");
    printf("4.信息查询\n");
    printf("5.退出系统\n\n");
    printf("=======================================================\n\n");
    printf("请输入您想要实现的功能(0--4):");
    scanf("%d", &c);
    switch (c)
    {
    case 1:
        input(n, m, w);
        break;
    case 2:
        output(n, m, w);
        break;
    case 3:
        sortput(n, m, w);
        break;
    case 4:
        search(n, m, w);
        break;
    case 5:
        printf("感谢使用,祝您天天开心!!\n");
        exit(0); //正常退出
    default:
        printf("您输入有误,请重新输入!");
        menu(n, m, w);
    }
}

//将信息写入文件中
void savetofile()
{
    FILE *fp; //定义一个文件指针
    int i;
    if (NULL == (fp = fopen("file.txt", "w")))
    {
        printf("打开文件失败!\n");
        return;
    }
    for (i = 0; i < N; i++)
    {
        if ('\0' != a[i].snum)
            if (fwrite(&a[i], sizeof(snode), 1, fp) != 1)
            {
                printf("存入信息失败!\n");
                return;
            }
    }
    fclose(fp); //关闭文件
}

//将信息从文件里取出
void readfromfile()
{
    int i;
    FILE *fp;
    if ((fp = fopen("file.txt", "rb")) == NULL)
    {
        printf("文件打开失败!\n");
        return;
    }
    for (i = 0; i < N; i++)
    {
        fread(&a[i], sizeof(snode), 1, fp);
    }
    fclose(fp);
}

//信息输入功能
void input(int n, int m, int w)
{
    int i, j, s, k, q = 1;
    for (i = 0; i < n; i++)
    {
        printf("请输入学校的编号:");
        scanf("%d", &a[i].snum);
        for (j = 0; j < m + w; j++)
        { //总的项目的输入
            printf("请输入项目编号:");
            scanf("%d", &a[i].t[j].inum);
            printf("请输入该项目取前3还是前5(输入3或5):");
            scanf("%d", &a[i].t[j].top);
            if (3 == a[i].t[j].top)
            {
                printf("获得的名次的个数(1--3):");
            }
            else if (5 == a[i].t[j].top)
            {
                printf("获得的名次的个数(1--5):");
            }
            else
            {
                printf("输入有误!程序退出....");
                return;
            }
            scanf("%d", &k); //输入获得名次的个数
            for (s = 0; s < k; s++)
            {
                if (3 == a[i].t[j].top)
                {
                    printf("请输入获得的名次(1--3):");
                }
                else
                {
                    printf("请输入获得的名次(1--5):");
                }
                scanf("%d", &a[i].t[j].range[s]); //输入所获得的名次的信息
            }
            printf("\n");
        }
    }
    for (i = 0; i < n; i++)
    {
        //初始化分数
        a[i].score = 0;  //学校总分
        a[i].mscore = 0; //男子总分
        a[i].wscore = 0; //女子总分
    }
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m + w; j++)
        {
            if (0 == i)
            {
                printf("项目%d取得是前3还是前5(输入3或5):", j + 1);
                scanf("%d", &a[i].t[j].top);
            }
            for (s = 0; s < 5; s++)
            {
                if (3 == a[i].t[j].top)
                { //如果是取前三
                    switch (a[i].t[j].range[s])
                    {
                    case 0:
                        a[i].t[j].mark[s] = 0;
                        break;
                    case 1:
                        a[i].t[j].mark[s] = 5;
                        break;
                    case 2:
                        a[i].t[j].mark[s] = 3;
                        break;
                    case 3:
                        a[i].t[j].mark[s] = 2;
                        break;
                    }
                }
                else if (5 == a[i].t[j].top)
                {
                    switch (a[i].t[j].range[s])
                    {
                    case 0:
                        a[i].t[j].mark[s] = 0;
                        break;
                    case 1:
                        a[i].t[j].mark[s] = 7;
                        break;
                    case 2:
                        a[i].t[j].mark[s] = 5;
                        break;
                    case 3:
                        a[i].t[j].mark[s] = 3;
                        break;
                    case 4:
                        a[i].t[j].mark[s] = 2;
                        break;
                    case 5:
                        a[i].t[j].mark[s] = 1;
                        break;
                    }
                }
                else if (a[i].t[j].top != 3 || a[i].t[j].top != 5)
                {
                    printf("信息输入错误!程序退出\n");
                    printf("\n");
                    exit(0);
                }
                a[i].score = a[i].score + a[i].t[j].mark[s]; //学校总分
                if (j < m)
                {
                    a[i].mscore = a[i].mscore + a[i].t[j].mark[s];
                }
                else
                { //女子总分
                    a[i].wscore = a[i].wscore + a[i].t[j].mark[s];
                }
            }
        }
    }
    printf("输入完毕!(返回菜单请输入1):");
    scanf("%d", &q);
    printf("\n");
    if (q != 1)
    {
        printf("不能再添加信息了!");
    }
    printf("\n");
    savetofile(); //保存文件
    menu(n, m, w);
}

#if (1)
void output(int n, int m, int w) /*2.统计输出*/
{
    readfromfile();
    int i, j, s, q = 0;
    for (i = 0; i < n; i++) /*显示结果*/
    {
        printf("学校编号:%d  学校总分:%d   男子总分:%d  女子总分:%d\n", a[i].snum, a[i].score, a[i].mscore, a[i].wscore);
        for (j = 0; j < m + w; j++)
        {
            printf("项目编号:%d  所取名次数量:%d\n", a[i].t[j].inum, a[i].t[j].top);
            for (s = 0; s < 5; s++)
            {
                if (a[i].t[j].range[s] != 0)
                    printf("名次:%d  分数:%d\n", a[i].t[j].range[s], a[i].t[j].mark[s]);
            }
        }
        printf("\n");
    }
    printf("\n");
    printf("统计完毕!返回?  1是 2否"); /*返回菜单*/
    scanf("%d", &q);
    printf("\n");
    if (q != 1)
        printf("统计已经结束!");
    printf("\n");
    menu(n, m, w);
}
#endif

//排序输出
void sortput(int n, int m, int w)
{
    readfromfile();
    int c, i, j, k, q = 0;
    int temp[N];
    printf("\t**************排序输出系统**************\n\n");
    printf("\t\t****1.按学校编号输出****\n");
    printf("\t\t****2.按学校总分输出****\n");
    printf("\t\t****3.按男子总分输出****\n");
    printf("\t\t****4.按女子总分输出****\n");
    printf("=======================================================\n\n");
    do
    {
        printf("请选择您想实现的功能的编号(1--4):");
        scanf("%d", &c);
        switch (c)
        {
        case 1:
            for (i = 0; i < n; i++)
            {
                temp[i] = i;
            }
            //用的是冒泡排序输出
            for (i = 0; i < n; i++)
            {
                for (j = i + 1; j < n; j++)
                {
                    if (a[temp[i]].snum > a[j].snum)
                    {
                        k = temp[i];
                        temp[i] = temp[j];
                        temp[j] = k;
                    }
                }
            }
            for (i = 0; i < n; i++)
            {
                printf("学校标号:%d  学校总分:%d  男子总分:%d   女子总分:%d\n", a[temp[i]].snum, a[temp[i]].score, a[temp[i]].mscore, a[temp[i]].wscore);
            }
            break;
        case 2:
            for (i = 0; i < n; i++)
            {
                temp[i] = i;
            }
            for (i = 0; i < n; i++)
            {
                for (j = i + 1; j < n; j++)
                {
                    if (a[temp[i]].score < a[j].score)
                    {
                        k = temp[i];
                        temp[i] = temp[j];
                        temp[j] = k;
                    }
                }
            }
            for (i = 0; i < n; i++)
            {
                printf("学校编号:%d  学校总分:%d   男子总分:%d   女子总分:%d\n", a[temp[i]].snum, a[temp[i]].score, a[temp[i]].mscore, a[temp[i]].wscore);
            }
            break;
        case 3:
            for (i = 0; i < n; i++)
            {
                temp[i] = i;
            }
            for (i = 0; i < n; i++)
            {
                for (j = i + 1; j < n; j++)
                {
                    if (a[temp[i]].mscore < a[j].mscore)
                    {
                        k = temp[i];
                        temp[i] = temp[j];
                        temp[j] = k;
                    }
                }
            }
            for (i = 0; i < n; i++)
            {
                printf("学校编号:%d  学校总分:%d  男团总分:%d  女团总分:%d\n", a[temp[i]].snum, a[temp[i]].score, a[temp[i]].mscore, a[temp[i]].wscore);
            }
            break;
        case 4:
            for (i = 0; i < n; i++)
            {
                temp[i] = i;
            }
            for (i = 0; i < n; i++)
            {
                for (j = i + 1; j < n; j++)
                {
                    if (a[temp[i]].wscore < a[j].wscore)
                    {
                        k = temp[i];
                        temp[i] = temp[j];
                        temp[j] = k;
                    }
                }
            }
            for (i = 0; i < n; i++)
            {
                printf("学校编号:%d  学校总分:%d  男团总分:%d  女团总分:%d\n", a[temp[i]].snum, a[temp[i]].score, a[temp[i]].mscore, a[temp[i]].wscore);
            }
            break;
        default:
            printf("您的输入有误!请从新输入...");
        }
        printf("请选择 1.返回主菜单  0.继续");
        scanf("%d", &q);
        printf("\n");
    }
    //=======================
    while (0 == q);
    printf("\n");
    //=======================
    if (q != 0)
    {
        menu(n, m, w);
    }
}

//查询功能
void search(int n, int m, int w)
{
    readfromfile();
    int c, i, j, k, d, l, q = 0;
    printf("\t****************查询系统****************\n\n");
    printf("\t\t****1.按学校编号查询****\n");
    printf("\t\t****2.按项目编号查询****\n");
    printf("=======================================================\n\n");
    do
    {
        k = -1;
        d = -1;
        l = -1;
        printf("请选择要实现功能的编号(1--2):");
        scanf("%d", &c);
        switch (c)
        {
        case 1:
            printf("要查询的学校编号:"); /*查找学校编号下标*/
            scanf("%d", &c);
            for (i = 0; i < n; i++)
            {
                if (c == a[i].snum)
                {
                    k = i;
                }
            }
            if (-1 == k)
            {
                printf("错误:这个学校没有参加此次运动会!\n");
            }
            else
            {
                printf("要查询的项目编号:"); /*查找项目编号下标*/
                scanf("%d", &c);
                for (j = 0; j < m + w; j++)
                {
                    if (c == a[k].t[j].inum)
                    {
                        d = j;
                    }
                }
                if (-1 == d)
                {
                    printf("此次运动会没有这个项目\n");
                }
                else
                {
                    printf("这个项目取前 %d名,该学校的成绩如下:\n", a[k].t[d].top);
                    for (i = 0; i < 5; i++)
                    {
                        if (a[k].t[d].range[i] != 0)
                        {
                            printf("名次:%d\n", a[k].t[d].range[i]);
                        }
                    }
                }
            }
            break;
        case 2:
            printf("要查询的项目编号:"); /*查找项目编号下标*/
            scanf("%d", &c);
            for (i = 0; i < n; i++)
            {
                for (j = 0; j < m + w; j++)
                {
                    if (c == a[i].t[j].inum)
                    {
                        l = j;
                    }
                    if (-1 == l)
                    {
                        printf("此次运动会没有该项目");
                    }
                    else
                    {
                        printf("该项目取前 %d名,取得名次的学校\n", a[0].t[l].top);
                        for (i = 0; i < n; i++)
                        {
                            for (j = 0; j < 5; j++)
                            {
                                if (a[i].t[l].range[j] != 0)
                                {
                                    printf("学校编号:%d,名次:%d\n", a[i].snum, a[i].t[l].range[j]);
                                }
                            }
                        }
                    }
                }
            }
            break;
        default:
            printf("输入错误,请重试!\n");
        }
        printf("请选择:1.返回主菜单 0.继续");
        scanf("%d", &q);
        printf("\n");
    } while (0 == q);
    printf("\n");
    if (q != 0)
    {
        menu(n, m, w);
    }
}

//主函数
int main()
{
    system("chcp 65001&cls"); //更改外部控制台编码为utf-8并清屏
    int n, m, w;              //n为学校个数,m为男子数,w为女子数
    printf("\t\t\t欢迎使用\t\t\t\t\n\n");
    printf("\t***********运动会分数统计系统***********\n\n");
    printf("请先输入运动会主要信息\n");
    printf("输入学校个数:");
    scanf("%d", &n);
    printf("输入男子项目个数:");
    scanf("%d", &m);
    printf("输入女子项目个数:");
    scanf("%d", &w);
    menu(n, m, w);
}

迷宫问题

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include <fstream>
#include <iostream>
#include <stdio.h>
using namespace std;
const int MAXLENGTH = 25;
typedef int MazeType[MAXLENGTH][MAXLENGTH]; // 迷宫数组[行][列]
const int MAXSIZE = 576;
const int OK = 1;
const int ERROR = 0;
MazeType m;      //声明一个全局迷宫对象m
int curstep = 1; //走的路径长度
typedef struct   //坐标
{
    int X;
    int Y;
} PosType; //坐标结构体
typedef struct
{
    int ord;      //通道块在路径上的“序号”
    PosType seat; //通道块在迷宫中的“坐标位置”
    int di;       //从从此通道块走向下一通道块的“方向”
} SElemType;      //栈的元素类型
typedef struct
{
    SElemType *base;
    SElemType *top;
    int stacksize;
} Stack;
int InitStack(Stack &S) // 构造一个空栈S
{
    S.base = new SElemType[MAXSIZE];
    S.top = S.base;
    S.stacksize = MAXSIZE;
    return OK;
}

int Push(Stack &S, SElemType e) //入栈
{
    if (S.top - S.base == S.stacksize)
    {
        return ERROR;
    }
    *(S.top)++ = e;
    return OK;
}

int Pop(Stack &S, SElemType &e) //出栈,移除当前栈顶元素
{
    if (S.top == S.base)
        return ERROR;
    e = *--S.top;
    return OK;
}

int StackEmpty(Stack S) //检测是否为空栈
{
    if (S.top == S.base)
        return OK;
    else
        return ERROR;
}
int Pass(PosType b) // 当迷宫m的b点的序号为1(可通过路径)
{
    if (m[b.X][b.Y] == 1)
        return OK;
    else
        return ERROR;
}
void FootPrint(PosType &a) // 使迷宫m的a点的序号变为足迹(curstep)
{
    m[a.X][a.Y] = curstep;
}
PosType NextPos(PosType c, int di) // 根据当前位置及移动方向,返回下一位置
{
    PosType dir[4] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // {行增量,列增量}
    //方向依次为上右下左
    c.X += dir[di].X;
    c.Y += dir[di].Y;
    return c;
}
void MarkPrint(PosType b)
{
    m[b.X][b.Y] = -1; // 使迷宫m的b点的序号变为-1(不能通过的路径)
}
int MazePath(PosType start, PosType end) // 若迷宫maze中存在从入口start到出口end的通道,则求得一条存放在栈中(从栈底到栈顶)
{
    Stack S;
    PosType curpos;
    SElemType e;
    InitStack(S);
    curpos = start; //把入口设置为当前位置
    do              //应为栈一开始是空的所以 do while
    {
        if (Pass(curpos))
        {                      // 当前位置可以通过,即是未曾走到过的通道块
            FootPrint(curpos); // 留下足迹
            e.ord = curstep;
            e.seat.X = curpos.X;
            e.seat.Y = curpos.Y; //当前位置
            e.di = 0;
            Push(S, e);                                 // 入栈当前位置及状态
            curstep++;                                  // 足迹加1
            if (curpos.X == end.X && curpos.Y == end.Y) // 到达终点(出口)
                return OK;
            curpos = NextPos(curpos, e.di); //将当前位置变为e.di方向上的临近通道块
        }
        else
        { // 当前位置不能通过
            if (!StackEmpty(S))
            {
                Pop(S, e);                          // 退栈到前一位置
                curstep--;                          //走的路径长度
                while (e.di == 3 && !StackEmpty(S)) // 前一位置处于最后一个方向(北),即当前位置的四周都无法通过
                {
                    MarkPrint(e.seat); // 留下不能通过的标记(-1)
                    Pop(S, e);         // 退回一步
                    curstep--;
                }
                if (e.di < 3) // 没到最后一个方向(北)
                {
                    e.di++; // 换下一个方向探索
                    Push(S, e);
                    curstep++;
                    curpos = NextPos(e.seat, e.di); // 设定当前位置是该新方向上的相邻块
                }
            }
        }
    } while (!StackEmpty(S));
    return ERROR;
}
void Print(int x, int y) // 输出迷宫图,0表示墙,1表示通路
{
    int i, j;
    for (i = 0; i < x; i++)
    {
        for (j = 0; j < y; j++)
            printf("%3d", m[i][j]);
        printf("\n");
    }
}
#define readDataPath "D:\\useful\\program\\dswork\\2maze\\shuju.txt"
int main()
{
    system("chcp 65001&cls"); //更改外部控制台编码为utf-8并清屏
    int X, Y, i, j, n;
    cout << "输入迷宫行列数(X,Y):";
    cin >> X >> Y;
    FILE *fp = fopen(readDataPath, "r"); //打开文件
    for (i = 0; i < X; i++)
    {
        for (j = 0; j < Y; j++)
        {
            fscanf(fp, "%d", &m[i][j]); /*每次读取一个数,fscanf函数遇到空格或者换行结束*/
        }
        fscanf(fp, "\n");
    }
    fclose(fp);
    PosType a, b;
    cout << "输入起点,终点下标:";
    cin >> a.X >> a.Y >> b.X >> b.Y;
    if (MazePath(a, b))
    {
        Print(X, Y);
    }
    else
    {
        cout << "没有路径可以到达" << endl;
    }
    system("pause");
}

行车路线问题

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <queue>
#include <string.h>
#include <vector>
using namespace std;
long long int n, m, t, a, b, c, ans, tmp, dist[505][3]; //0前面的节点是大路的最小疲劳 1前面节点是小路的最小疲劳 2到此为止小路的长度
bool vis[505], f;
const long long int inf = 0x7f7f7f7f7f7f7f7f;
struct Path
{
    long long int c;
    Path()
    {
        c = inf;
    }
} path[505][505], path1[505][505];
deque<int> q;

int main()
{
    scanf("%d%d", &n, &m); //路口(1~n)和道路的数量
    for (int i = 0; i < m; i++)
    {
        scanf("%d%d%d%d", &t, &a, &b, &c);
        if (t == 0)
        {
            path[a][b].c = path[a][b].c < c ? path[a][b].c : c; //可能有重复的边 存小的
            path[b][a] = path[a][b];
        }
        else
        {
            path1[a][b].c = path1[a][b].c < c ? path1[a][b].c : c;
            path1[b][a] = path1[a][b];
        }
    }
    memset(vis, 0, sizeof(vis));
    memset(dist, 0x7f, sizeof(dist));
    for (int i = 1; i <= n; i++)
        dist[i][2] = 0;
    dist[1][0] = dist[1][1] = 0;
    q.push_back(1);
    vis[1] = true;
    while (!q.empty())
    { //spfa主代码
        int v = q.front();
        q.pop_front();
        vis[v] = 0;
        for (int i = 2; i <= n; i++)
        {
            f = false;
            if (path[v][i].c != inf)
            { //大路
                if (dist[v][0] != inf && path[v][i].c != inf && dist[v][0] + path[v][i].c < dist[i][0])
                {
                    dist[i][0] = dist[v][0] + path[v][i].c;
                    f = true;
                }
                if (dist[v][1] != inf && path[v][i].c != inf && (dist[v][1] + path[v][i].c < dist[i][0]))
                {
                    dist[i][0] = dist[v][1] + path[v][i].c;
                    f = true;
                }
            }
            if (path1[v][i].c != inf)
            { //小路
                if (dist[v][0] != inf && path1[v][i].c != inf && dist[v][0] + path1[v][i].c * path1[v][i].c < dist[i][1])
                {
                    dist[i][1] = dist[v][0] + path1[v][i].c * path1[v][i].c;
                    f = true;
                    dist[i][2] = path1[v][i].c;
                }
                if (dist[v][1] != inf && path1[v][i].c != inf)
                {
                    long long int tmp = dist[v][1] - dist[v][2] * dist[v][2] + (path1[v][i].c + dist[v][2]) * (path1[v][i].c + dist[v][2]);
                    if (tmp < dist[i][1])
                    {
                        dist[i][1] = tmp;
                        f = true;
                        dist[i][2] = dist[v][2] + path1[v][i].c;
                    }
                }
            }
            if (f && vis[i] == 0)
            {
                vis[i] = true;
                q.push_back(i);
            }
        }
    }
    printf("%lld\n", min(dist[n][0], dist[n][1]));
    system("pause");
    return 0;
}

线索化二叉树

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#include <bits/stdc++.h>
#include <conio.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

typedef enum
{
    Link,
    Thread
} Pointertag;

typedef struct Tree_Node
{
    struct Tree_Node *left;
    struct Tree_Node *right;
    char ch;
    Pointertag ltag;
    Pointertag rtag;
} Tree;

Tree *pre;

void menu()
{
    system("cls");
    printf("********************\n");
    printf("1.构建二叉树\n");
    printf("2.先序线索化\n");
    printf("3.中序线索化\n");
    printf("4.后序线索化\n");
    printf("********************\n");
}

Tree *create(FILE *fp)
{
    Tree *tree;
    char ch;
    if (!fp)
        fp = fopen("info.txt", "r");
    fscanf(fp, "%c", &ch);
    if (ch == '@')
        tree = NULL;
    else
    {
        tree = (Tree *)malloc(sizeof(Tree));
        tree->ch = ch;
        tree->left = create(fp);
        tree->right = create(fp);
    }
    return tree;
}

void in_thread(Tree_Node *root, Tree_Node **ptmp)
{
    if ((root == NULL))
        return;

    in_thread(root->left, ptmp);

    if (root->left == NULL)
    {
        root->left = *ptmp;
        root->ltag = Thread;
    }
    if (*ptmp != NULL && (*ptmp)->right == NULL)
    {
        (*ptmp)->right = root;
        (*ptmp)->rtag = Thread;
    }

    (*ptmp) = root;
    in_thread(root->right, ptmp);
    return;
}

Tree_Node *in_thread_nextNode(Tree_Node *root)
{
    Tree_Node *ret = NULL;

    if (root == NULL)
        return ret;
    if (root->rtag == 1) // 右标志位 1,可以直接得到后继节点
    {
        ret = root->right;
    }
    else // 右标志位0,则要找到右子树最左下角的节点
    {
        ret = root->right;
        while (ret->ltag == 0) // 查找最左下节点的位置
        {
            ret = ret->left;
        }
    }
    return ret;
}

void in_thread_Older_next(Tree_Node *root)
{
    if (root == NULL)
        return;

    while (root->ltag == 0) // 查找中序遍历的第一个节点,当ltag == 0的话
        root = root->left;

    printf("%c ", root->ch); // 访问第一个节点

    while (root->right != NULL) // 当root存在后继,依次访问后继节点
    {
        root = in_thread_nextNode(root);
        printf("%c ", root->ch);
    }

    printf("\n");
    return;
}

void preOrderThread(Tree_Node *root)
{
    if (root == NULL)
        return;
    if (root->left == NULL)
    {
        root->ltag = Thread;
        root->left = pre;
    }
    if (pre && pre->right == NULL)
    {
        pre->rtag = Thread;
        pre->right = root;
    }

    pre = root;

    if (root->ltag == Link) //防止栈溢出
        preOrderThread(root->left);
    if (root->rtag == Link)
        preOrderThread(root->right);
}

void preOrder(Tree_Node *root)
{
    if (root == NULL)
        return;
    Tree_Node *cur = root;
    while (cur)
    {
        while (cur && cur->ltag == Link)
        {
            printf("%c ", cur->ch);
            // cout <<  << " ";
            cur = cur->left;
        }
        printf("%c ", cur->ch);
        // cout << cur->ch << " ";
        //将该树的后继当成子树来访问
        cur = cur->right;

        while (cur && cur->rtag == Thread)
        {
            cur = cur->right;
            printf("%c ", cur->ch);
        }
        cur = cur->right;
    }
}

template<class T>
void Thread_Binary_tree<T>::PreOrder_Thread_Op(BT_Thread_Node<T>* &Tree)
{
 if (Tree == NULL)
  return;
 
 if (Tree->Left_Child == NULL)  //根
 {
  Tree->Ltag = Thread;
  Tree->Left_Child = Pre_Node;
 }
 
 if (Pre_Node != NULL && Pre_Node->Right_Child == NULL)
 {
  Pre_Node->Rtag = Thread;
  Pre_Node->Right_Child = Tree;
 }
 
 Pre_Node = Tree;
 if (Tree->Ltag == Link)
  PreOrder_Thread_Op(Tree->Left_Child);  //左孩子节点
 if (Tree->Rtag == Link)
  PreOrder_Thread_Op(Tree->Right_Child);  //右孩子节点
 
}


void midThread(Tree *tree)
{
    if (tree)
    {
        midThread(tree->left);
        printf("%c ", tree->ch);
        if (!tree->left)
        {
            tree->ltag = Thread;
            tree->left = pre;
        }
        if (!tree->right)
            tree->rtag = Thread;
        if (pre && pre->rtag == Thread)
            pre->right = tree;
        pre = tree;
        midThread(tree->right);
    }
}

void backThread(Tree *tree)
{
    if (tree)
    {
        backThread(tree->left);
        backThread(tree->right);
        printf("%c ", tree->ch);
        if (!tree->left)
        {
            tree->ltag = Thread;
            tree->left = pre;
        }
        if (!tree->right)
            tree->rtag = Thread;
        if (pre && pre->rtag == Thread)
            pre->right = tree;
        pre = tree;
    }
}

int main()
{
    system("chcp 65001&cls"); //更改外部控制台编码为utf-8并清屏
    int mode;
    Tree *tree, *midthtree;
    FILE *fp = NULL;
    tree = create(fp);
    while (1)
    {
        menu();
        scanf("%d", &mode);
        pre = NULL;
        switch (mode)
        {
        case 1:
            printf("先序线索化结果如下:");
            preOrderThread(tree);
            preOrder(tree);
            tree = create(fp);
            printf("键入任意键返回");
            _getch();
            break;
        case 2:
            printf("中序线索化结果如下:");
            midThread(tree);
            tree = create(fp);
            printf("键入任意键返回");
            _getch();
            break;
        case 3:
            printf("后序线索化结果如下:");
            backThread(tree);
            tree = create(fp);
            printf("键入任意键返回");
            _getch();
            break;
        }
    }
}
// DFBAEC  FDBECA

索引文件问题

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#include <bits/stdc++.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#define MaxRec 100   //最多的记录个数
typedef struct Index //定义索引文件结构
{
    int no;      //学号
    long offset; //主文件中的记录号
} Index;
typedef struct
{
    int no;               //学号
    char name[10];        //姓名
    int age;              //年龄
    char sex[5];          //性别
    int deg1, deg2, deg3; //课程1-课程3成绩
} StudType;
void InsertSort(Index R[], int n) //采用直接插入排序法对R[0..n-1]按学号递增排序
{
    int i, j;
    Index temp;
    for (i = 1; i < n; i++)
    {
        temp = R[i];
        j = i - 1;
        while (j >= 0 && temp.no < R[j].no)
        {
            R[j + 1] = R[j]; //将关键字大于R[i].key的记录后移
            j--;
        }
        R[j + 1] = temp; //在j+1处插入R[i]
    }
}
void CreatIdxFile() //建立索引文件
{
    FILE *mfile, *idxfile;
    Index idx[MaxRec];
    StudType st;
    int n = 0, i;
    if ((mfile = fopen("stud.dat", "rb")) == NULL)
    {
        printf("  提示:不能打开主文件\n");
        return;
    }
    if ((idxfile = fopen("index.dat", "wb")) == NULL)
    {
        printf("  提示:不能建立索引文件\n");
        return;
    }
    i = 0;
    while ((fread(&st, sizeof(StudType), 1, mfile)))
    {
        idx[i].no = st.no;
        idx[i].offset = ++n;
        i++;
    }
    InsertSort(idx, n); //对idx数组按no值排序
    rewind(idxfile);
    for (i = 0; i < n; i++)
        fwrite(&idx[i], sizeof(Index), 1, idxfile);
    fclose(mfile);
    fclose(idxfile);
    printf("  提示:索引文件建立完毕\n");
}
void OutputMainFile() //输出主文件全部记录
{
    FILE *mfile;
    StudType st;
    int i = 1;
    if ((mfile = fopen("stud.dat", "rb")) == NULL)
    {
        printf("  提示:不能读主文件\n");
        return;
    }
    printf("                ----学生成绩表----\n");
    printf("记录号  学号     姓名   年龄 性别 语文 数学 英语\n");
    while ((fread(&st, sizeof(StudType), 1, mfile)) == 1)
    {
        printf("%6d%5d%10s%6d%5s%5d%5d%5d\n", i, st.no, st.name, st.age, st.sex, st.deg1, st.deg2, st.deg3);
        i++;
    }
    fclose(mfile);
}
void OutputIdxFile() //输出索引文件全部记录
{
    FILE *idxfile;
    Index irec;
    printf("     ----学生索引表----\n");
    printf("\t学号  记录号\n");
    if ((idxfile = fopen("index.dat", "rb")) == NULL)
    {
        printf("  提示:不能读索引文件\n");
        return;
    }
    while ((fread(&irec, sizeof(Index), 1, idxfile)) == 1)
        printf("\t%5d%6ld\n", irec.no, irec.offset);
    fclose(idxfile);
}
void ReadIndexFile(Index idx[MaxRec], int &n) //读索引文件数据存入idx数组中
{
    int j;
    FILE *idxfile;
    if ((idxfile = fopen("index.dat", "rb")) == NULL)
    {
        printf("  提示:索引文件不能打开\n");
        return;
    }
    fseek(idxfile, 0, 2);
    j = ftell(idxfile); //j求出文件长度
    rewind(idxfile);
    n = j / sizeof(Index); //n求出文件中的记录个数
    fread(idx, sizeof(Index), n, idxfile);
    fclose(idxfile);
}
int SearchNum(Index idx[], int n, int no) //在含有n个记录的索引文件idx中查找学号为no的记录对应的记录号
{
    int mid, low = 0, high = n - 1;
    while (low <= high) //二分查找
    {
        mid = (low + high) / 2;
        if (idx[mid].no > no)
            high = mid - 1;
        else if (idx[mid].no < no)
            low = mid + 1;
        else //idx[mid].no==no
            return idx[mid].offset;
    }
    return -1;
}
void FindStudent() //输出指定学号的记录
{
    int no;
    FILE *mfile;
    Index idx[MaxRec];
    StudType st;
    int i, n;
    if ((mfile = fopen("stud.dat", "rb+")) == NULL)
    {
        printf("  提示:主文件中没有任何记录\n");
        return;
    }
    ReadIndexFile(idx, n); //读取索引数组idx
    printf("输入学号:");
    scanf("%d", &no);
    i = SearchNum(idx, n, no); //在idx中查找
    if (i == -1)
        printf("  提示:学号%d不存在\n", no);
    else
    {
        fseek(mfile, (i - 1) * sizeof(StudType), SEEK_SET); //由记录号直接跳到主文件中对应的记录
        fread(&st, sizeof(StudType), 1, mfile);
        printf("%5d%10s%6d%5s%5d%5d%5d\n", st.no, st.name, st.age, st.sex, st.deg1, st.deg2, st.deg3);
    }
    fclose(mfile);
}
void WriteFile(StudType st[], int n) //将st数组中的n个学生记录写入stud.dat文件中
{
    int i;
    FILE *fp;
    if ((fp = fopen("stud.dat", "wb")) == NULL)
    {
        printf("\t提示:不能创建stud.dat文件\n");
        return;
    }
    for (i = 0; i < n; i++)
        fwrite(&st[i], 1, sizeof(StudType), fp);
    fclose(fp);
    printf("  提示:文件stud.dat创建完毕\n");
}
int main()
{
    system("chcp 65001&cls"); //更改外部控制台编码为utf-8并清屏
    int n = 8, sel;           //n为实际学生人数
    StudType st[] = {{1, "陈华", 20, "男", 78, 90, 84},
                     {5, "张明", 21, "男", 78, 68, 92},
                     {8, "王英", 20, "女", 86, 81, 86},
                     {3, "刘丽", 21, "女", 78, 92, 88},
                     {2, "许可", 20, "男", 80, 83, 78},
                     {4, "陈军", 20, "男", 78, 88, 82},
                     {7, "马胜", 21, "男", 56, 67, 75},
                     {6, "曾强", 20, "男", 78, 89, 82}};
    printf("建立主文件\n");
    WriteFile(st, n); //建立主文件
    do
    {
        printf("1:输出主文件 2:建索引文件 3:输出索引文件 4:按学号查找 0:退出:");
        scanf("%d", &sel);
        switch (sel)
        {
        case 1:
            OutputMainFile();
            break;
        case 2:
            CreatIdxFile();
            break;
        case 3:
            OutputIdxFile();
            break;
        case 4:
            FindStudent();
            break;
        }
    } while (sel != 0);
    return 0;
}