中国大学MOOC-陈越,何钦铭数据结果起步能力自测题 1~5题全解析

突然写这个是因为,昨天陈越姥姥在比赛介绍中说,学数据结构之前可以试试这套题,如果不能在半天之内写出来说明基础知识还不够扎实,不能很好的理解数据结构的妙用。
本来想打题目的,但是想了下,会来看的人应该都是看着题目找过来的,就懒得占篇幅了。直接写思路吧,因为最近在弄c++比较多,所以基本就用c++了,但是和C的差距也不大,无非是用了vector代替数组,反正数据结构基本还是要用C++写的,对应的&引用没了解过的可以把他当指针理解

自测一:


思路:分析沙漏的符号和层数的关系,得出我们要输出的层数(我的方法是先输出上半层,所以这里分析的上半层)
分析一下符号总数和上半层数之间的关系
floor sum
1 1
2 7
3 17
4 31
可以得出关系sum=2floorfloor-1;
上半层沙漏的层数 floor=pow((sum+1)/2,0.5);

开始着手打印
上半层每层的个数(n)与层数(floor)之间的关系,这里从只有一个符号的那一层开始算
n=2floor-1;
空格的关系就是最高层减去当前层
space=floorMax-floorTemp;

倒三角类似,不打第一个元素的的一行

#include<stdio.h>
#include<math.h>

int display(int num,char shape);

int main()
{
    int num=25;
    char shape;
    scanf("%d %c", &num,&shape);
    printf("%d", display(num,shape));
    return 0;
}

int display(int num,char shape)
{
    int floor;
    int last;
    int tempSpace = 0;
    int temp = 0;

    floor = pow((double)(num + 1)/2,0.5);
    last = num - 2 * floor * floor + 1;

    //上半部分正三角打印
    for (int i = floor; i > 0; i--)
    {
        tempSpace = floor - i;
        temp = 2*i- 1;
        while (tempSpace)
        {
            printf(" ");
            tempSpace--;
        }

        while (temp)
        {
            printf("%c",shape);
            temp--;
        }
        printf("\n");
    }

	//下半部分倒三角打印
    for (int i = floor-1; i > 0; i--)
    {
        tempSpace = i-1;
        while (tempSpace)
        {
            printf(" ");
            tempSpace--;
        }

        temp =2*(floor-i)+1;
        while (temp)
        {
            printf("%c",shape);
            temp--;
        }
        printf("\n");
    }
    return last;
}

自测-2


思路题目写的花里胡哨,其实就是求差为2的素数,先求出从2-n的素数存入数组arr,方便等下查找,然后遍历整个数组统计arr[i]-arr[i-1]=2的个数

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int main()
{
	
	int n;
	cin>>n;
	 
    //先求出2到n的素数的个数,并存入数组arr中
	 vector<int> arr;
	 for(int i=2;i<=n;i++)
	 {
	 	int j;
	 	for( j=2;j<=sqrt(i);j++)
	 	{
	 		if(i%j==0)
	 		{
	 			break;
			 }
		 }
		 if(j>sqrt(i))
		 {
		 	arr.push_back(i);
		 }
	  } 
	  
    
    //计算素数对
	  int count=0;
	  for(int i=1;i<arr.size();i++)
	  {
	  	if(arr[i]-arr[i-1]==2)
	  	{
	  		count++;
		  }
	  }
	  
	  cout<<count;
 } 

自测3


思路
可以写一个颠倒的函数,假设要移的位置为n,数组长度为m,调用3次就可以实现题目要求,也没有使用多余的数组,空间复杂度为1。第一次把整个颠倒,第二次从0-(n-1)颠倒,第三次从n-m颠倒
举个小例子
1 2 3 4 5 6
第一次 6 5 4 3 2 1
第二次 5 6 4 3 2 1
第三次 5 6 1 2 3 4 完成题目要求

#include<iostream>
#include<vector>
using namespace std;

void exch(vector<int> &a,int n,int m);
int main()
{
	int m,n;
	cin>>m>>n;
    n%=m;

	//数据存入数组a中
	vector<int> a(m);
	int i;
	for(i=0;i<m;i++)
	{
		cin>>a[i];
	}

	//调用函数
	exch(a,0,m);
	exch(a,0,n);
	exch(a,n,m);

	//输出结果
	for(i=0;i<m;i++)
	{
        if(i!=m-1)
		cout<<a[i]<<' ';
        else cout<<a[i];
	}
}

//逆转函数
void exch(vector<int> &a,int n,int m)
{
	int temp,i;
	int maxi=(n+m)/2;
	for(i=n;i<maxi;i++)
	{
		temp=a[i];
		a[i]=a[m-1];
		a[m-1]=temp;
		m--;
	}
}

自测四


思路
这个题目的意思就是给你一串数字,将他2然后看他个位数字的组成,如果和2之前的数字组成一样的话,就输出yes否则就输出no,还要打印*2的结果。
主要难点就是在这个数使用long long int会溢出,因此选用字符串存储输入,结果的话用int数组存储比较好。在输入之后用一个循环将各个位的数字存入adjust[10]数组中,类似于计数排序。然后乘的时候每个位置先乘,乘完之后再处理进位,得到结果之后将结果每一位从adjust中减去,如果处理完之后adjust每一个下标上的值都为0的话,则输出yes,否则输出no,再打印结果

#include<bits/stdc++.h>

using namespace std;
int main()
{
	string s1;
	cin>>s1;
    
    //建立一个比s1长1的数组存储结果
	vector<int> result(s1.length()+1);
    //计数,将s1中各数字的个数存储在数组中,然后再将result中数字的个数剪掉
	vector<int> adjust(10,0); 
	int i;
    //计算结果,先不处理进位
	for(i=0;i<s1.length();i++)
	{
		result[i+1]=(s1[i]-'0')*2;
		adjust[s1[i]-'0']++;
	}
	//处理进位
	for(i=result.size()-1;i>=0;i--)
	{
		if(result[i]>=10)
		{
			result[i-1]+=result[i]/10;
			result[i]%=10;
		}
		
		adjust[result[i]]--;
	}
	//如果result第一位是0,则可能存在多减了一个0的状态
	if(result[0]==0)
	{
		adjust[0]++;
	}
	//如果adjust有元素不为0,则证明初始数据和结果数字组成不相同
	for(i=0;i<adjust.size();i++)
	{
		if(adjust[i]!=0)
		{
			cout<<"No"<<endl; 
			break;
		}
	}
	
	if(i==adjust.size())
	{
		cout<<"Yes"<<endl;
	}
	//输出结果,如果第一个数字为0则不输出
	for(i=0;i<result.size();i++)
	{
		if(i==0&&result[0]==0)
		{
			
		}else{
			cout<<result[i];
		}
	}
 } 

自测五


思路
这个题大意就是将一组牌进行排序,有一个数组card(这个数组要自己输入,我用了一个类数组来存储 。 c中的结构体也可以存储,或者直接string数组也可以。为了方便输出我还重载了一下<<运算符),然后将每个数组下标对应的牌放到数组下index标中所存值的位置。这样我们建立一个swap函数多次调用就好了。
可以先建立一个数组temp备份swap每次接收的数组arr,然后for循环index,将对应的temp[i]放入arr[ index[i] ]中,这里使用引用,因为值传递太浪费时间了。

#include<iostream>
#include<vector>
using namespace std;

class card {
public:
	char ch;
	int num;

	//重载<<运算符
	friend ostream& operator<<(ostream& os,const card &a)
	{
		os << a.ch << a.num;
		return os;
	}
};

void swap(int* temp, vector<card>& arr);
int main()
{

	//存入卡牌信息
	vector<card> arr(54);
	for (int i = 0; i < 54; i++)
	{
		if (i < 13)
		{
			arr[i].ch = 'S';
			arr[i].num = i + 1;
		}
		else if (i < 26)
		{
			arr[i].ch = 'H';
			arr[i].num = i - 12;
		}
		else if (i < 39)
		{
			arr[i].ch = 'C';
			arr[i].num = i - 25;
		}
		else if (i < 52)
		{
			arr[i].ch = 'D';
			arr[i].num = i - 38;
		}
		else
		{
			arr[i].ch = 'J';
			arr[i].num = i - 51;
		}
	}
	
	
	int m;
	cin >> m;
	//存入调换顺序信息
	int* num = new int[54];
	for (int i = 0; i < 54; i++)
	{
		cin >> num[i];
	}

	//多次调用swap
	while (m--)
	{
		swap(num, arr);
	}
	//输出结果,末尾无空格
	for (int i = 0; i < 54; i++)
	{
        if(i!=53)
        {
            cout<<arr[i]<<' ';
        }else
        {
    		cout << arr[i];            
        }
	}
}

//用于调换顺序的函数
void swap(int* num, vector<card>& arr)
{
	//记一下数据
	vector<card> temp;
	temp = arr;	
	for (int i = 0; i < 54; i++)
	{
		arr[num[i]-1] = temp[i];
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下坠丷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值