计算概论A代码总结Ⅰ(基础算法类)

本blog对笔者遇到的相关问题和代码进行总结。本期是第一期:基础算法类

Ⅰ、矩阵操作类

1.回形遍历

//回形遍历
#include<iostream>
#include<cmath>
#include<memory.h>
#include<algorithm>
int a[20][20];
using namespace std;
int ans[500];
int num = 0;
void print() {
	for (int i = 0; i < num - 1; i++) {
		cout << ans[i] << ' ';
	}
	cout << ans[num - 1] << endl;
}
int main(){
	int n, m;
	cin >> n >> m;
	int nn = n; int mm = m;
	int sum = n * m;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> a[i][j];
		}
	}
	int i = 0; int j = 0;

	while (sum) {
		for (; i < nn; i++) {
			ans[num] = a[i][j]; num++;
			sum--;
			if (sum == 0) {
				print(); return 0;
			}
		}
		i--;
		j++;
		for (; j < mm; j++) {
			ans[num] = a[i][j]; num++;
			sum--;
			if (sum == 0) {
				print(); return 0;
			}
		}
		j--;
		i--;
		for (; i >= n - nn; i--) {//这里要取等
			ans[num] = a[i][j]; num++;
			sum--;
			if (sum == 0) {
				print(); return 0;
			}
		}
		i++;
		j--;
		for (; j > m - mm; j--) {//因为回到了边界所以不能取等
			ans[num] = a[i][j]; num++;
			sum--;
			if (sum == 0) {
				print(); return 0;
			}
		}
		i++;
		j++;
		mm--;
		nn--;
	}

	return 0;
}

2.环形矩形输出(上例的变形)

//环形矩形输出
#include<iostream>
using namespace std;
int ans[10][10];
void print(int a) {//打印a*a方阵
	for (int i = 0; i < a; i++) {
		for (int j = 0; j < a; j++) {
			cout << ans[i][j] << ' ';
		}
		cout << endl;
	}
}
int main() {

	int n;
	cin >> n;
	int row = n; int col = n;
	int sum = n * n;
	int i = 0; int j = 0;
	int num = 1;
	while (sum) {
		for (; j < col; j++) {//right
			ans[i][j] = num++;
			sum--;
			if (sum == 0) {
				print(n);
				return 0;
			}
		}
		i++;
		j--;
		for (; i < row; i++) {//down
			ans[i][j] = num++;
			sum--;
			if (sum == 0) {
				print(n);
				return 0;
			}
		}
		j--;
		i--;
		for (; j >= n - col; j--) {//left
			ans[i][j] = num++;
			sum--;
			if (sum == 0) {
				print(n);
				return 0;
			}
		}
		j++;
		i--;
		for (; i > n - row; i--) {
			ans[i][j] = num++;
			sum--;
			if (sum == 0) {
				print(n);
				return 0;
			}
		}
		i++;
		j++;
		row--;
		col--;
	}return 0;
}

3.对角遍历


//对角线遍历矩阵
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 100;
int matrix[maxn][maxn];
int n, m;
void print() {
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			cout << matrix[i][j] << ' ';
		}
		cout << endl;
	}
}
int main() {

	cin >> m >> n;
	//m*n
	int count = m + n - 1;//对角线遍历次数
	int row=0; int col=0;
	int num = 0;
	for (int i = 0; i < count; i++) {//发现对角线的数字规律是关键@!
		if (i % 2 == 0) {
			//向右上遍历
			while (row >= 0 && col < n) {
				matrix[row][col] = num;
				num++;
				row--; col++;
			}
			if (col < n) {
				row++;
			}
			else { row += 2; col -= 1; }
		}
		else {
			while (col >= 0 && row < m) {
				matrix[row][col] = num;
				num++;
				col--; row++;
			}
			if (row < m) {
				col++;
			}
			else { col += 2; row--; }
		}
	}
	print();

}

4.对角遍历变式

 

//对角遍历变形:顺便练习了递归,也没那么难hh
#include<iostream>
#include<cmath>
#include<math.h>
int matrix[4][4] = {
{0,2,5,9},
{1,4,8,12},
{3,7,11,14},
{6,10,13,15}
};//看好题目嗷
int ans;
void F(int x, int y, int n) {
	if (n <= 0)return;
	int temp = pow(4, n - 1);
	int a = 0; int b = 0;
	for (; a < 4; a++) {
		if (x >= a * temp&&x < (a + 1)*temp) {
			break;
		}
	}/
	for (; b < 4; b++) {
		if (y >= b * temp&&y < (b + 1)*temp) {
			break;
		}
	}//在(a,b)大子块内
	ans += matrix[a][b] * temp*temp;
	x = x - a * temp;
	y = y - b * temp;//在新的小矩形内重复上述判断
	F(x, y, n - 1);
	return;
}
using namespace std;
int main() {
	int n, x, y; ans = 0;
	while (cin >> n >> x >> y) {
		if (n == 0)return 0;
		ans = 0;
		F(x, y, n);
		cout << ans << endl;
	}
	return 0;

}

二、字符串操作类

1.大整数乘法

//大整数乘法
#include<iostream>
#include<string>
const int maxn = 10010;
int res[maxn];
using namespace std;
int main() {//统计上小数位就能改成小数乘法
	string s1, s2;
	cin >> s1 >> s2;
	int l1 = s1.length();
	int l2 = s2.length();
	for (int i = 0; i < l1; i++) {
		for (int j = 0; j < l2; j++) {
			res[i + j] = (s1[i] - '0')*(s2[j] - '0');
		}
	}
	if (res[0] >= 10)cout << res[0] / 10;
	for (int i = l1 + l2 - 1; i > 0; i--) {
		if (res[i] >= 10) {
			res[i - 1] += res[i] / 10;
			res[i] %= 10;
		}
	}
	for (int i = 0; i < l1 + l2 - 1; i++) {
		cout << res[i];
	}
	return 0;
}

2.大整数加法

//大整数加法
#include<iostream>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<memory.h>
const int maxn = 100;
using namespace std;
int main() {
	int n;
	cin >> n;
	while(n--){
	string s1, s2;
	int k;
	cin >> k >> s1 >> s2;
	int num1[maxn], num2[maxn];
	memset(num1, 0, sizeof(num1));
	memset(num2, 0, sizeof(num2));//这样就不用讨论了
	int l1 = s1.length();
	int l2 = s2.length();
	num1[0] = s1[0] - 48;//直接赋值相当于赋值ascii码
	num2[0] = s2[0] - 48;
	for (int i = 1; i < l1 - 1; i++) {
		num1[i] = s1[i + 1] - 48;
	}
	for (int i = 1; i < l2 - 1; i++) {
		num2[i] = s2[i + 1] - 48;
	}
	for (int i = max(l1, l2) - 2; i >= 1; i--) {
		num2[i] = num1[i] + num2[i];//统一存在num2里
		if (num2[i] >= k) {
			num2[i] -= k;
			num2[i - 1] += 1;
		}
	}
	cout << num2[0] << '.';
	int length = max(l1, l2);
	while (num2[length - 1] == 0) { length--; }
	if (length == 0)continue;
	for (int i = 1; i < length; i++) {
		cout << num2[i];
	}
	cout << endl;
}
	return 0;
}

3.拨钟问题

 

//拨钟问题
#include<iostream>
using namespace std;
int main() {
	int z[10];
	int i[10];
	for (int i = 1; i <= 9; i++) {
		cin >> z[i];
	}
	int sum = 0;
	int ans[20];
	int num = 0;
	for ( i[1] = 0; i[1] < 4; i[1]++) {
		for (i[2] = 0; i[2] < 4; i[2]++) {
			for (i[3] = 0; i[3] < 4; i[3]++) {
				for (i[4] = 0; i[4] < 4; i[4]++) {
					for (i[5] = 0; i[5] < 4; i[5]++) {
						for (i[6] = 0; i[6] < 4; i[6]++ ) {//每个操作执行的次数
							for (i[7] = 0; i[7] < 4; i[7]++) {
								for (i[8] = 0; i[8] < 4; i[8]++) {
									for (i[9] = 0; i[9] < 4; i[9]++) {
										sum = 0;//每次操作前都归0
										sum += (z[1] + i[1] + i[2] + i[4]) % 4;
										sum += (z[2] + i[1] + i[2] + i[3] + i[5]) % 4;
										sum += (z[3] + i[2] + i[3] + i[6]) % 4;
										sum += (z[4] + i[1] + i[4] + i[5] + i[7]) % 4;
										sum += (z[5] + i[1] + i[3] + i[5] + i[7] + i[9]) % 4;
										sum += (z[6] + i[3] + i[5] + i[6] + i[9]) % 4;
										sum += (z[7] + i[4] + i[7] + i[8]) % 4;
										sum += (z[8] + i[5] + i[7] + i[8]+i[9]) % 4;
										sum += (z[9] + i[6] + i[8] + i[9]) % 4;
										//怎么确定是最小?循环次数最小?
										if (sum == 0) {
											for (int j = 1; j <= 9; j++) {
												while (i[j]--) 
													ans[num++]= j;
												
											}
											for (int i = 0; i < num - 1; i++) {
												cout << ans[i] << ' ';
											}cout << ans[num - 1] << endl;
											return 0;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}

4.两个日期之间的天数

//日期之间的距离
#include<iostream>
using namespace std;

bool R(int i) {
	return i % 4 == 0 && i % 100 != 0 || i % 400 == 0;//闰年返回1
}
struct P {
	int y;
	int m;
	int d;
};
int main() {
	int year[2] = { 365,366 };
	int day[2][12] = { {31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31} };
	P start, end;
	cin >> start.y >> start.m >> start.d;
	cin >> end.y >> end.m >> end.d;
	int ans = 0;
	for (int i = start.y; i < end.y; i++) {
		int temp = R(i);
		ans += year[temp];//先算上一共隔着多少年
	}
	//算下初始的距离1.1多少天
	int ans1 = 0; int temp1 = R(start.y);
	for (int i = 0; i < start.m-1;i++) {
		ans1 += day[temp1][i];
	}
	ans1 += start.d;
	int ans2 = 0; int temp2 = R(end.y);
	for (int i = 0; i < end.m - 1; i++) {
		ans2 += day[temp2][i];
	}
	ans2 += end.d;
	int ret = ans - ans1 + ans2;
	cout << ret << endl;; return 0;
}

三、补充类

//setw控制输出间隔
//setfill控制输出填空;在iomanip里
#include<iomanip>
#include<iostream>
using namespace std;
int main() {
	cout << setfill('x')<<setw(5)  << 1 << endl;//setw和setfill位置可以互换。但是二者和被输出内容的前后不同输出样貌不同
	//除了setfill外一定要有额外的输出,这样才能输出
	cout << 1 << setw(5) << setfill('5') << endl;//这样就填不上了
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值