zoukankan      html  css  js  c++  java
  • 题目--找鞍点 及 选择排序和冒泡排序

    2019年春季学期第四周作业:

    作业课程 C语言程序设计II
    作业要求 2019年春季学期第四周作业
    课程目标 背熟栈,队列,向量函数
    从作业中得到的帮助 更加熟练两种基本排序算法(冒泡排序和选择排序)
    参考文献 挑战程序设计

    第一题:

    7-1 找鞍点 (20 分)

    一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。

    本题要求编写程序,求一个给定的n阶方阵的鞍点。

    输入格式:

    输入第一行给出一个正整数n(1n6)。随后n行,每行给出n个整数,其间以空格分隔。

    输出格式:

    输出在一行中按照“行下标 列下标”(下标从0开始)的格式输出鞍点的位置。如果鞍点不存在,则输出“NONE”。题目保证给出的矩阵至多存在一个鞍点。

    输入样例1:

    4
    1 7 4 1
    4 8 3 6
    1 6 1 2
    0 7 8 9

    输出样例1:

    2 1

    输入样例2:

    2
    1 7
    4 1

    输出样例2:

    NONE

    此题是一道简单的搜索题,也就是先确认一个点,然后沿4个方向搜索到不满足条件的数(不越界的情况下),然后返回需要的值。由于题目给的条件非常非常非常小,所以不需要考虑复杂度,逻辑通了随便写。

    AC代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int arr[10][10];//n<6,直接定义一个全局变量
     5 bool solve(int n,int x,int y){
     6    for(int i = 0; i < n ; i++)
     7    if(arr[x][y]<arr[x][i])return false;//搜索行,找到一个大于确认的点的值直接返回
     8    for(int j = 0; j < n ; j++)
     9    if(arr[x][y]>arr[j][y])return false;//搜索列,找到一个小于确认的点的值直接返回
    10    
    11    return true;
    12 }
    13 
    14 int main ( int argc , const char * argv[])
    15 {
    16     int n,flag;
    17     cin>>n;
    18     for(int i=0;i<n;i++)for(int j=0;j<n;j++){cin>>arr[i][j];}//给数组赋值
    19     
    20      for(int i=0;i<n;i++)
    21      for(int j=0;j<n;j++)
    22      if(solve(n,i,j)){cout<<i<<" "<<j;flag++;}//找到满足条件的鞍点就输出(虽然题目说给的矩阵至多一个鞍点,但懒得弄就直接判断所有的点是否为鞍点吧)
    23      if(!flag)cout<<"NONE";//没有鞍点则输出NONE
    24     return 0;
    25 }

    设计思路

    本题调试过程中遇到的问题及解决方法

    由于是一遍AC的,暂无任何疑问。

    运行结果截图

    第二题

    7-2 选择法排序 (20 分)

    本题要求将给定的n个整数从大到小排序后输出。

    输入格式:

    输入第一行给出一个不超过10的正整数n。第二行给出n个整数,其间以空格分隔。

    输出格式:

    在一行中输出从大到小有序的数列,相邻数字间有一个空格,行末不得有多余空格。

    输入样例:

    4
    5 1 7 6

    输出样例:

    7 6 5 1

    首先提一下,三种基本排序方法(冒泡,选择,插入)在N久之前就写了很多遍的东西..这次写也没花多久直接一遍过了,只能说这周问题比较面向初次了解排序算法的人,我接下来会把选择排序和“挑战题”冒泡排序(挑战题有加分吧?手动滑稽)稍微写详细点,因为自己也很久没写过了,帮助记忆一下。

    AC代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 void solve(int arr[],int n){
     5     for(int i=0;i<n-1;i++){   //首先理所当然solve里面第一个要做的事情就是做一个内外循环,外循环要少一次,防止最后两个元素重复。
     6         int maxs=arr[i];  //重置maxs的值,maxs就是各轮循环处理中,第i号到第N-1号元素中的最大值
     7         int sz_zb=i;      //重置sz_zb的值,sz_zb就是各轮循环处理中,第i号到第N-1号元素中最大值的下标
     8     for(int j=i;j<n;j++){if(maxs<arr[j]){maxs=arr[j] ; sz_zb=j;} }    //找出第i号到第N-1号中的最大值及其下标    
     9           int tmp = arr[i] ;
    10              arr[i] = maxs;     //交换第i号和对应的最大值的元素的位置
    11              arr[sz_zb] = tmp;             
    12      }
    13      for(int i=0;i<n;i++)
    14      if(i<n-1)
    15      cout<<arr[i]<<" ";
    16      else cout<<arr[i];  //从大到小输出数组
    17 
    18 }
    19 
    20 int main ( int argc , const char * argv[])
    21 {
    22     int n,num[12];
    23     cin>>n;
    24     for(int i=0;i<n;i++)
    25     cin>>num[i];
    26     
    27     solve(num,n);
    28     return 0;
    29 }

    设计思路

    本题调试过程中遇到的问题及解决方法

    虽然是一遍AC的,但还是提醒一下,一定要理解内外循环的概念及作用,不然排序会出错

    运行结果截图

    注意一下,选择排序的复杂度,假设数据总数为N,那么无论在哪一种情况下,选择排序都要进行(N-1)+(N-2)+.....+1=(N^2-N)/2次比较运算,用于搜索未排序部分的最小值,因此该算法的复杂度与N^2基本成正比,及复杂度数量级为O(N^2).使用时要看题目条件范围是否过大,如果过大建议选择其他排序算法。

    挑战题

    7-1 冒泡法排序 (10 分)

    输入1个正整数n(1<=n<=10),然后输入n个整数并存放在数组中,将这n个整数从大到小排序后输出,相邻数字间有一个空格,行末不得有多余空格。

    输入格式:

    输入第一行给出一个不超过10的正整数n。第二行给出n个整数,其间以空格分隔。

    输出格式:

    在一行中输出从大到小有序的数列,相邻数字间有一个空格,行末不得有多余空格。

    输入样例:

    4 
    75 71 77 76

    输出样例:

    77 76 75 71

    冒泡排序算法的时间复杂度与选择排序的时间复杂度是基本一样的,也是要做(N^2-N)/2次比较,所以复杂度也为O(N^2).只是排序的过程略有不同,选择排序是每次遍历,找出未排序的数中最大的一个,然后将它放在最前面,而冒泡排序则是从第一个数(未排序好的数)开始,一个一个往后比较,遇到比自己大的则交换位置,直到无法交换为止,最后排完所有的数后一定是从大到小的顺序。

    AC代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 void solve(int arr[],int n)
     5 {
     6     for(int i = n - 1 ; i > 0 ; i--)
     7       for(int j = 0 ; j < i ; j++)
     8         {
     9             if( arr[j] < arr[j+1] ){int tmp = arr[j];arr[j]=arr[j+1];arr[j+1]=tmp;}
    10         }
    11     
    12             for(int i = 0 ; i < n ; i++)
    13                if(i<n-1)cout<<arr[i]<<" ";
    14                 else cout<<arr[i];
    15 }
    16 int main ( int argc , const char * argv[] )
    17 {
    18     int n;
    19     cin>>n;
    20     int arr[12]; 
    21     for( int i = 0 ; i < n ; i++)cin>>arr[i];
    22     solve(arr,n);
    23     return 0;
    24 }

    设计思路

    本题调试过程中遇到的问题及解决方法

    此题是一道较为简单的基础排序题,未遇到任何问题。

    运行结果截图

    写到这里为了能更加区别冒泡和选择排序的区别,我改一下代码将每一次排序的过程运行图发出来。

    冒泡排序:

     选择排序:

    稍微注意观察一下,排序过程的差异很明显。

    最后还是分享一下利用partition进行快排的算法,是一个很经典及实用的排序算法,博客地址:https://www.cnblogs.com/xiangqi/p/10485379.html

    学习总结: 存在的问题 心得 完成作业消耗时间 本周学习内容
    第一周 对文件读取数据的运用不是很熟练 多去看关于刷题的书籍,有助于提高自己写题能力,实在不会的可以参考大佬的代码,加以自己理解之后去默写几遍 半个小时左右 文件输入,BFS,DFS,PARTITION算法及简单的贪心算法
    第二周 对单纯用数组完成双向链表的操作还是太生疏了,说明对双向链表的运作原理不熟 推荐两本比较好的书《挑战程序设计》《算法竞赛》 半个小时左右 vector数组及list双向链表操作

     

    再分享本周预习题的解法,写到了另外一篇博客,这里是地址:https://www.cnblogs.com/xiangqi/p/10573623.html

    ------------------------不用看了,这里没了-----------------------

  • 相关阅读:
    VC++实现感染文件式加载DLL文件
    vC++实现遍历桌面和快速启动里的所有快捷方式,判断快捷方式是不是浏览器,如果是则删除快捷方式参数
    VC++另类实现进程插入
    云服务系列:Windows Azure SDK for .NET(2012 年 6 月发布的版本)的最新消息
    VC++1.5K字节实现下载并远程注入
    上海求职指南 (最新版)
    WinAPI: GetWindowText 获取窗口标题
    WinAPI: SetCursorPos 设置鼠标指针位置
    WinAPI: SetComputerName 更改计算机名称
    GDI+ 学习记录(31): 图像颜色变换(TGPImageAttributes)
  • 原文地址:https://www.cnblogs.com/xiangqi/p/10560695.html
Copyright © 2011-2022 走看看