Chinaunix首页 | 论坛 | 博客
  • 博客访问: 434028
  • 博文数量: 67
  • 博客积分: 2468
  • 博客等级: 上尉
  • 技术积分: 1050
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-05 01:21
文章分类

全部博文(67)

文章存档

2013年(1)

2012年(65)

2011年(1)

分类: C/C++

2012-05-26 10:37:53

1.选秀节目打分,分为专家评委和大众评委,score[] 数组里面存储每个评委打的分数,judge_type[] 里存储与 score[] 数组对应的评委类别,judge_type == 1,表示专家评委,judge_type == 2,表示大众评委,n表示评委总数。打分规则如下:专家评委和大众评委的分数先分别取一个平均分(平均分取整),然后,总分 = 专家评委平均分  * 0.6 + 大众评委 * 0.4,总分取整。如果没有大众评委,则 总分 = 专家评委平均分,总分取整。函数最终返回选手得分。

函数接口
int cal_score(int score[], int judge_type[], int n)

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int cal_score(int score[], int judge_type[], int n);

  4. int
  5. main(int argc, char *argv[])
  6. {
  7.     int total_score;
  8.     int n = 8;
  9.     int data[] = { 95, 92, 87, 90, 85, 88, 82, 85 };
  10.     int type[] = { 1, 2, 2, 1, 2, 2, 1, 2 };
  11.     
  12.     total_score = cal_score(data, type, n);
  13.     printf("total_score is : %d\n", total_score);
  14.     
  15.     return 0;
  16. }

  17. /*
  18.  *打分函数:总分 = 专家评委平均分 * 0.6 + 大众评委 * 0.4
  19.  */
  20. int
  21. cal_score(int score[], int judge_type[], int n)
  22. {
  23.     int sum_expert = 0;
  24.     int sum_common = 0;
  25.     int count_expert = 0;
  26.     int count_common = 0;
  27.     int avg_expert, avg_common;
  28.     int final_score;
  29.     int i;
  30.     
  31.     for(i = 0; i < n; i++){
  32.         if(judge_type[i] == 1){
  33.             sum_expert += score[i];
  34.             count_expert++;
  35.         } else if(judge_type[i] == 2){
  36.             sum_common += score[i];
  37.             count_common++;
  38.         } else {
  39.             printf("Error type!");
  40.         }
  41.     }
  42.     
  43.     avg_expert = sum_expert / count_expert;
  44.     avg_common = sum_common / count_common;
  45.     final_score = avg_expert * 0.6 + avg_common * 0.4;
  46.     
  47.     return final_score;
  48. }

2.给定一个数组input[] ,如果数组长度n为奇数,则将数组中最大的元素放到 output[] 数组最中间的位置,如果数组长度n为偶数,则将数组中最大的元素放到 output[] 数组中间两个位置偏右的那个位置上,然后再按从大到小的顺序,依次在第一个位置的两边,按照一左一右的顺序,依次存放剩下的数。
例如: input[] = {3, 6, 1, 9, 7}   output[] = {3, 7, 9, 6, 1};
       input[] = {3, 6, 1, 9, 7, 8}    output[] = {1, 6, 8, 9, 7, 3}

数接口
void sort(int input[[, int n, int output[])

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. void sort(int input[], int n, int output[]);

  4. int
  5. main(int argc, char *argv[])
  6. {
  7.     int i;
  8.     int n = 10;
  9.     int input[] = { 3, 6, 1, 9, 7, 10, 12, 15, 18, 19 };
  10.     int output[n];
  11.     
  12.     printf("input is :\n");
  13.     for(i = 0; i < n; i++){
  14.         printf("%d ", input[i]);
  15.     }
  16.     printf("\n");
  17.     
  18.     sort(input, n, output);
  19.     
  20.     printf("output is :\n");
  21.     for(i = 0; i < n; i++){
  22.         printf("%d ", output[i]);
  23.     }
  24.     printf("\n");
  25.     
  26.     return 0;
  27. }

  28. /*
  29.  *先把input数组的数从大到小排列,再按照要求放到output数组中。
  30.  */
  31. void
  32. sort(int input[], int n, int output[])
  33. {
  34.     int i, j, tmp;
  35.     int *max_ptr;
  36.     int *fill_ptr = input;
  37.     
  38.     for(j = 0; j < n; j++){
  39.         tmp = *fill_ptr;
  40.         max_ptr = fill_ptr;
  41.         for(i = j; i < n; i++){
  42.             if(input[i] > tmp){
  43.                 tmp = input[i];
  44.                 max_ptr = &input[i];
  45.             }
  46.         }
  47.         if(max_ptr != fill_ptr){
  48.             tmp = *fill_ptr;
  49.             *fill_ptr = *max_ptr;
  50.             *max_ptr = tmp;
  51.         }
  52.         fill_ptr++;
  53.     }
  54.     
  55.     int *left, *right;
  56.     
  57.     if(n % 2){
  58.         output[n/2] = input[0];
  59.         left = &output[n/2 - 1];
  60.         right = &output[n/2 + 1];
  61.         
  62.         for(i = 1; i < n; i++){
  63.             if(i % 2){
  64.                 *left = input[i];
  65.                 left--;
  66.             } else {
  67.                 *right = input[i];
  68.                 right++;
  69.             }
  70.         }
  71.     } else {
  72.         left = &output[n/2 - 1];
  73.         right = &output[n/2];
  74.         
  75.         for(i = 0; i < n; i++){
  76.             if(!(i % 2)){
  77.                 *left = input[i];
  78.                 left--;
  79.             } else {
  80.                 *right = input[i];
  81.                 right++;
  82.             }
  83.         }
  84.     }
  85.     
  86. }

3.操作系统任务调度问题。操作系统任务分为系统任务和用户任务两种。其中,系统任务的优先级 < 50,用户任务的优先级 >= 50且 <= 255。优先级大于255的为非法任务,应予以剔除。现有一任务队列task[],长度为n,task中的元素值表示任务的优先级,数值越小,优先级越高。函数scheduler实现如下功能,将task[] 中的任务按照系统任务、用户任务依次存放到 system_task[] 数组和 user_task[] 数组中(数组中元素的值是任务在task[] 数组中的下标),并且优先级高的任务排在前面,数组元素为-1表示结束。
例如:task[] = {0, 30, 155, 1, 80, 300, 170, 40, 99}
      system_task[] = {0, 3, 1, 7, -1}
      user_task[] = {4, 8, 2, 6, -1}

函数接口
void scheduler(int task[], int n, int system_task[], int user_task[])

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define DEBUG 0

  4. void scheduler(int task[], int n, int system_task[], int user_task[]);

  5. int
  6. main(int argc, char *argv[])
  7. {
  8.     int n, i, j;
  9.     int task[] = {0, 30, 155, 1, 80, 300, 170, 40, 99};
  10.     n = sizeof(task) / sizeof(int);
  11.     int system_task[n];
  12.     int user_task[n];

  13.     scheduler(task, n, system_task, user_task);

  14.     printf("\ntask[] is :\n");
  15.     for(i = 0; i < n; i++){
  16.         printf("%d ", task[i]);
  17.     }
  18.     
  19.     printf("\n\nsystem_task[] is :\n");
  20.     for(i = 0; i < n && system_task[i] != -1; i++){
  21.         printf("%d ", system_task[i]);
  22.     }
  23.     printf("%d",system_task[i]);
  24.     
  25.     printf("\n\nuser_task[] is :\n");
  26.     for(i = 0; i < n && user_task[i] != -1; i++){
  27.         printf("%d ", user_task[i]);
  28.     }
  29.     printf("%d", user_task[i]);
  30.     printf("\n");

  31. }

  32. /*
  33.  *scheduler处理函数
  34.  */
  35. void
  36. scheduler(int task[], int n, int system_task[],int user_task[])
  37. {
  38.     int i, j, min_val;
  39.     int min_in_task_ptr;
  40.     int *fill_ptr;
  41.     int *task_ptr[n];
  42.     int **tmp_ptr_ptr;

  43.     for(i = 0; i < n; i++){
  44.         task_ptr[i] = &task[i];
  45.     }

  46.     /*将task_ptr[]从小到大的排列*/
  47.     for(i = 0; i < n; i++){
  48.         min_val = *task_ptr[i];
  49.         min_in_task_ptr = i;
  50.         fill_ptr = task_ptr[i];

  51.         /*寻找task_ptr后面的最小值和它的指针*/
  52.         for(j = i; j < n; j++){
  53.             if(*task_ptr[j] < min_val){
  54.                 min_val = *task_ptr[j];
  55.                 min_in_task_ptr = j;
  56.             }
  57.         }
  58. #if DEBUG
  59.         printf("min_val:%d min_ptr:%d ", min_val, *task_ptr[min_in_task_ptr]);
  60.         printf("min_ptr-task:%d\n", min_in_task_ptr);
  61. #endif

  62.         /*交换指针*/
  63.         task_ptr[i] = task_ptr[min_in_task_ptr];
  64.         /*min_ptr-task怎么和我期望的有差距呢?
  65.          * 哦,task数组中的数据顺序没有变化。
  66.          * */
  67.         //task_ptr[i] = task_ptr[min_ptr - task];
  68.         task_ptr[min_in_task_ptr] = fill_ptr;
  69. #if DEBUG
  70.         printf("%d\ttask_ptr[] is :", i);
  71.         for(j = 0; j < n; j++){
  72.             printf("%d ", *task_ptr[j]);
  73.         }
  74.         printf("\n");
  75. #endif

  76.     }

  77.     int count_sys = 0;
  78.     int count_user = 0;

  79.     for(i = 0; i < n; i++){
  80.         if(*task_ptr[i] < 50){
  81.             system_task[count_sys] = task_ptr[i] - task;
  82.             count_sys++;
  83.         } else if(*task_ptr[i] > 255){
  84.             printf("%d", *task_ptr[i]);
  85.         } else {
  86.             user_task[count_user] = task_ptr[i] - task;
  87.             count_user++;
  88.         }
  89.     }
  90.     system_task[count_sys] = -1;
  91.     user_task[count_user] = -1;
  92. }

总结:
看到一个师弟对这个三道题目的评价“其实就是逻辑思维,根本不涉及库函数算法神马的。。。”
嗯,对于我来说,着重练习的是逻辑思维,GDB调试。

编这三个练习的时候我感觉到比华为杯2012西南赛区初赛题目要顺手一些。特别是对于调试也“身”有体会了。看了《GDB调试程序[陈皓]》后,感觉原来GDB还不错。同时,也喜欢上了在程序中加上条件编译,这样调试程序就更方便了。目前我的调试前后的时间各占了一半,我还会做得更好的。

喜欢GDB的打印数组 p *task_ptr[0]@9 。开始对这个的理解错误,运行结果让我匪夷所思。原来
p task_ptr[0]@9 才是打印排了序的指针。但显示的是指针,不容易阅读。此时,我想起了条件编译,感觉不错。

在第三个练习中,用了指针数组,用得还不太熟悉。(暂且忽略解决方法的好坏~)尽管看书的时候,指针的应用都能理解,但和自己动手相比差别还是大。

阅读(797) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~