数据结构_起步自测_C++题解

DS_起步自测

中国大学MOOC_陈越、何钦铭_数据结构_起步能力自测题

1. 打印沙漏

思路:先用一个循环计算出有多少行,最长行有多少个符号,这里计算时直接用N去减,可以得到剩余的符号数;后面直接用计算得到的行数和每行多少个去打印图形

#include<iostream>
using namespace std;
int main()
{
	int n;
	char symbol;
	cin >> n >> symbol;
	
	if (n < 1)	return 0;
	n = n - 1;
	int max_row = 1;
	int row_num = 0;
	while(n >= 0){
		if (n - 2 * (max_row + 2) < 0)	break;
		max_row += 2;
		++row_num;
		n -= max_row * 2;
	}
	for (int i = 0; i < row_num; i++){
		for (int j = 0; j < i; j++){
			cout << " ";
		}
		for (int j = 0; j < max_row - 2 * i; j++){
			cout << symbol;
		}
		cout << endl;
	}
	for (int i = row_num; i >= 0; i--){
		for (int j = 0; j < i; j++){
			cout << " ";
		}
		for (int j = 0; j < max_row - 2 * i; j++){
			cout << symbol;
		}
		cout << endl;
	}
	cout << n;
	return 0;
}

2 素数对猜想

思路:判断素数的函数直接默写;因为判断相邻素数,直接用一个变量记录上一个素数,再与新得到的素数比较

#include<iostream>
using namespace std;
bool isPrime(int num){
	if (num == 0 || num == 1) return false;
	for (int i = 2; i * i <= num; i++){
		if (num % i == 0) return false;
	}
	return true;
}
int main()
{
	int n;
	cin >> n;
	int count = 0;
	int lastPrime = 2;
	for (int i = 3; i <= n; i++){
		if (isPrime(i)){
			if (i - lastPrime == 2) ++count;
			lastPrime = i;
		}
	}
	cout << count;
	return 0;
}

3 数组元素循环右移问题

思路

如果移动未知数比数组大小还要大,说明移动了超过一个循环,实际位置变化应为 (移动位置数%数组大小),这样处理后可保证移动位置数小于数组大小。

输出时先输出后m-1个数,再输出前面部分,为保证末尾没有多余空格,中间点单独输出。这样操作只是按移动后的顺序输出,但实际并没有去交换数据,数组里的数据顺序并没有变,虽然可以通过,但不知道是不是简化了题意。

#include<iostream>
using namespace std;
int main()
{
	int n, m;
	cin >> n >> m;
	m = m % n;
	int *data = new int[n];
	for (int i = 0; i < n; i++){
		cin >> data[i];
	}
	for (int i = n - m; i < n; i++){
		cout << data[i] << " ";
	}
	for (int i = 0; i < n - m - 1; i++){
		cout << data[i] << " ";
	}
	cout << data[n-m-1] << endl;
	return 0;
}

4 Have Fun with Numbers

思路

  • 最长可能输入20位整数,long long也有可能会溢出,只能用字符串处理。
  • 注意string的每一位是一个char,做计算注意-'0'
  • 自己实现计算,准备一个进位项,由于只做翻倍,可简单判断此位>5进位项为1,否则为0
  • 由于翻倍后可能位数+1,预设翻倍后的char数组时按+1大小来开,计算结束后,通过判断最高位,将正确的char赋到字符串中去,后面用字符串来处理
  • 判断是否是原数的数字调换顺序,只要组成两个数的数字个数都对应即可确定。
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
int main()
{
	string ori_num;
	cin >> ori_num;
	bool isPermutation = true;
	int ori_bitnum[10] = {0};
	char *double_num = new char[ori_num.length()+1];
	if (ori_num[0] >= '5') isPermutation = false;
	char carry = '0';
	for (int i = ori_num.length(); i > 0; i--){
		double_num[i] = (ori_num[i-1] - '0') * 2 % 10 + carry;
		carry = ori_num[i-1] < '5'? '0': '1';
		++ori_bitnum[ori_num[i-1]-'0'];
	}
	double_num[0] = carry;
	string double_numstr = carry != '0'? double_num: double_num + 1;
	if(isPermutation){
		int double_bitnum[10] = {0};
		for (int i = 0; i < ori_num.length()+1; i++){
			++double_bitnum[double_numstr[i]-'0'];
		}
		for (int i = 0; i < 10; i++){
			if (ori_bitnum[i] != double_bitnum[i]){
				isPermutation = false;
				break;
			}
		}
	}
	printf("%s\n",isPermutation? "Yes": "No");
	cout << double_numstr;
	return 0;
}

5 Shuffling Machine

思路:多开一个数组,按给定的顺序将原数组的卡片内容赋过去,如果多次操作,就将新的数组搬运到原数组中去。

#include<iostream>
#include<string>
using namespace std;
string cards[54];
string new_cards[54];
void copyCards(){
	for (int i = 0; i < 54; i++){
		cards[i] = new_cards[i];
	}
}
int main()
{
	for (int i = 0; i < 54; i++){
		if (i < 13){
			cards[i] = "S";
			cards[i].append(to_string(i+1));
		}else if (i < 26){
			cards[i] = "H";
			cards[i].append(to_string(i-12));
		}else if (i < 39){
			cards[i] = "C";
			cards[i].append(to_string(i-25));
		}else if (i < 52){
			cards[i] = "D";
			cards[i].append(to_string(i-38));
		}else{
			cards[i] = "J";
			cards[i].append(to_string(i-51));
		}
	}
	int k;
	cin >> k;
	int order[54];
	for (int i = 0; i < 54; i++){
		cin >> order[i];
	}
	for (int j = 0; j < k; j++){
		for (int i = 0; i < 54; i++){
			new_cards[order[i]-1] = cards[i];
		}
		copyCards();
	}
	for (int i = 0; i < 53; i++){
		cout << cards[i] << " ";
	}
	cout << cards[53];
	return 0;
}
posted @ 2019-04-11 12:03  鲸90830  阅读(197)  评论(0)    收藏  举报