蓝桥杯算法入门_02 (结构体 - R进制 - 回文判断)

#include <iostream>
using namespace std;
#include <cstring>
#include<algorithm>
/*老师要表扬每门课前四名 , 总分前四名 ,如果同分数情况下 ,字典序更小的先表扬
   班级人数   4<=N <= 100

5
Alice 99 98 97 96
Bob 98 97 96 94
Coy 94 94 95 96
Dan 93 95 96 97
Evan 0 94 95 95



*/

struct Student_01 {
	char name[105];
	int score[4];
};

Student_01 stu[105];
bool cmp1_01(Student_01 a,Student_01 b) { //保证成绩相同时不会乱
	if(a.score[0] != b.score[0]) {
		return a.score[0] > b.score[0];
	}
	return strcmp(a.name,b.name) < 0;
}
bool cmp2_01(Student_01 a,Student_01 b) { //保证成绩相同时不会乱
	if(a.score[1] != b.score[1]) {
		return a.score[1] > b.score[1];
	}
	return strcmp(a.name,b.name) < 0;
}
bool cmp3_01(Student_01 a,Student_01 b) { //保证成绩相同时不会乱
	if(a.score[2] != b.score[2]) {
		return a.score[2] > b.score[2];
	}
	return strcmp(a.name,b.name) < 0;
}
bool cmp4_01(Student_01 a,Student_01 b) { //保证成绩相同时不会乱
	if(a.score[3] != b.score[3]) {
		return a.score[3] > b.score[3];
	}
	return strcmp(a.name,b.name) < 0;
}
bool cmp5_01(Student_01 a,Student_01 b) { //总分前四
	int suma = 0,sumb = 0;
	for(int i = 0; i < 4; i++) {
		suma += a.score[i];
		sumb += b.score[i];
	}
	if(suma != sumb) {
		return suma > sumb;
	}
	return strcmp(a.name,b.name) < 0;
}
void print_01() {
	for(int i = 0; i < 4; i++) {
		printf("%s ",stu[i].name);
	}
	printf("\n"); //换行
}

void test_01() {
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; i++) {
		scanf("%s",stu[i].name);
		for(int j = 0; j < 4 ; j++) {
			scanf("%d",&stu[i].score[j]);
		}
	}
	sort(stu,stu + n,cmp1_01);
	print_01();
	sort(stu,stu + n,cmp2_01);
	print_01();
	sort(stu,stu + n,cmp3_01);
	print_01();
	sort(stu,stu + n,cmp4_01);
	print_01();
	sort(stu,stu + n,cmp5_01);
	print_01();
	return;
}

/*摘气球
按跳到矮的先摘  每个小朋友都会把能够得到 气球的摘了
小朋友高度都不一样



10 10
1 2 3 4 5 6 7 8 9 10
3 1 4 6 7 8 9 9 4 12
//1.人数 气球数
//2.小朋友跳起来的高度
//3.每个气球的高度


输出 摘到气球 的数量
1
0
1
2
0
1
1
1
2
0
*/

//三个数组 ,一个标记气球是否使用 ,一个统计高度 ,一个统计答案

struct Children_02 {
	int a;  //够得着的 高度
	int id;
};
Children_02 child[1005];
bool cmp_02_1(Children_02 a,Children_02 b) {
	return a.a < b.a;
}

void test_02() { //O(n)
	int h[100005];  //实际测试放全局才行AC    否则乱码  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	int ans[100005];
	bool used[100005];
	int n,m,p;  //n 人数, m 输入气球数量   ,p 指针
	scanf("%d%d",&n,&m);
	for(int i = 0; i <n; i++) { //跳起来的高度
		scanf("%d",&child[i].a);
		child[i].id = i;
	}
	for(int i = 0; i < m; i++) { //气球的高度
		scanf("%d",&h[i]);
	}
	sort(child,child + n,cmp_02_1);   //按高度从小到大排
	sort(h,h + m); //整理气球高度
	p = 0;
	for(int i = 0; i < n; i++) {
		while(p < m && h[p] <= child[i].a) {  //刚好指针又可以表示气球数量 ,前面拿完的气球后面拿不了
			ans[child[i].id]++;
			p++;
		}
	}
	for(int i = 0; i < n; i++) {
		cout<< ans[i]<<endl;
	}
	return;
}

/*   ***快速提升代码能力
思维 转换成 计算机编程能力

常见的写法 技巧

1.代码结合 层次 缩进 快捷键 Ctrl Shift a

避免低级错误
参考文章: 程序设计竞赛中的调试技巧


*/
//放main容易爆栈 ,
/*
a + b  T个数
T未给范围 ,不能开全局变量 边读入边输出
5
1 2
3 4
5 6
7 8
9 10


*/
void test_03() {
	int T,a,b;
	cin>>T;
	for(int i = 1; i <= T ; i++) {
		cin>> a >> b;
		//scanf("%d%d",&a,&b);
		cout<< a+b <<endl;
	}

	return;
}

/*斐波那契数列
f(n) = f(n - 1)+ f(n - 2);
f(n) mod 1000000007 (10^9 + 7)

*/
const int mod_04 = 1e9 + 7;   //1e9   一 e 九
int f_04[100005];
void test_04() {
	int n;
	cin >> n;
	f_04[1] = 1;
	f_04[2] = 1;
	for(int i = 3; i <= n; i++) {
		f_04[i] = (f_04[i - 1] + f_04[i - 2]) % mod_04;

	}
	cout<<f_04[n] <<endl;
}

/*矩阵旋转 90°

//1.行列
//2.矩阵
3 4
-1 3 6 3
7 7 9 1
10 3 4 6

//刚好为每列逆序 后 变每行
10 7 -1
3 7 3
4 9 6
6 1 3

n行 --> i = 0 开始i列     !!!直接输出就可以 ,不用真的把原来的旋转 !
否则新建一个数组存放
*/
int num_05[205][205];
void test_05() {
	int n,m;
	cin>> n >> m;
	for(int i = 0; i < n; i++) {   //快速行列建立矩阵
		for(int j = 0; j < m; j++) {
			cin >> num_05[i][j];
		}
	}
	for(int i = 0; i < m; i++) { //输出m行n列
		for(int j = 0; j < n; j++) {
			if(j != n - 1) //这是为了每行最后一个不要空格" " ,可能被判格式错误!!
				cout <<num_05[n - j - 1][i] <<" ";
			else {
				cout<< num_05[n - j - 1][i] <<endl;
			}
		}
	}
	return;
}

/*求和最大的子矩阵
输入第一行n,m(1<=n,m<=50) 行 列
接下来输入矩阵

3 3
2 -4 1
-1 2 1
4 -2 2

输出
6

输出一个数 表示最大子矩阵的元素和
*/

int A_06[55][55];
void test_06() {
	int n,m,ans;
	cin>> n >> m ; //回车就换行 不用endl 换行
	ans = -1005 ;//保证答案数值最小,也能更新ans
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			cin>>A_06[i][j];
		}
	}
	for(int i = 0; i < n; i++) { //上    枚举上下左右边界   用 up down left right 更好
		for(int j = i; j < n; j++) { //下
			for(int k = 0; k < m; k++) { //左
				for(int l = k; l < m; l++) { //右
					int tmp = 0;
					for(int p = i; p <= j; p++) {  //遍历子矩阵 上到下
						for(int q = k ; q <= l; q++) { // 左到右
							tmp += A_06[p][q];  //累加
						}
					}
					if(tmp > ans) {
						ans = tmp;  //更新
					}
				}
			}
		}
	}
	cout<< ans <<endl;
}


/*去重  、 排序

样例:
10
20 40 32 67 40 20 89 300 400 15


*/

#include<set>

void test_set_01() {
	set<int>s1;
	int n,elem;
	cin >> n;
	for (int i = 0; i < n ; i++) { //my利用set去重排序
		scanf("%d",&elem);
		s1.insert(elem);
	}
	cout<<s1.size()<<endl;
	for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
		cout << *it <<" ";
	return ;
}


int num_07[105],ans[105];

void test_07() {
	int n,m;  //n原大小 , m记录新的大小
	cin>>n;
	for(int i = 0; i < n; i++) {
		scanf("%d",&num_07[i]);
	}
	sort(num_07,num_07+n);
	m= 0;
	for(int i = 0; i < n; i++) {
		if(i != 0 && num_07[i] != num_07[i - 1]) {
			ans[m++] = num_07[i - 1];
		}
	}
	ans[m++] = num_07[n - 1];
	cout<< m << endl;
	for(int i = 0; i < m; i++) {
		if(i != m - 1) { //最后一个换行 且后面没有空格格式
			cout<< ans[i] << " ";
		} else {
			cout<< ans[i] << endl;
		}
	}
}

/*
N,l1,r1,l2,r2

个数 区间1(从小到大)   区间2 (从大到小)
第二行 数据

输出新的 序列

样例:
6 1 3 2 4
8 3 1 6 9 2

输出
1 8 6 3 9 2
*/

int A_08[10005];
void test_08() {
	int N,l1,r1,l2,r2;
	cin>>N>>l1>>r1>>l2>>r2;
	for(int i = 1; i <= N; i++) { //这里是从1开始填入
		cin>> A_08[i] ;
	}
	sort(A_08+l1,A_08+r1+1);//先从小到大
	sort(A_08+l2,A_08+r2+1,greater<int>()); //再从大到小
	for(int i = 1; i <= N; i++) { //从1开始输出
		if(i != N) {
			cout<< A_08[i] <<" ";
		} else {
			cout<< A_08[i] <<endl;
		}
	}
	return;
}

/*输入一个十进制数   进制  ****************** 除基取余法  N % R ,N / R;

N<= 10000 , 2<= R <= 16, 注意N可能是负数
输出R进制数

用 'A' 表示 10 , 'B' 表示 11   ...
样例:
数 进制
23 12

转换结果
18

*/

char ans_09[105];
void test_09() {  //留下来对R取余的结果 ,但结果是反的,所以先存下来 ,然后倒序输出
	int N,R,m,now;
	cin >> N >>R;
	if(N < 0) {
		cout<< "-";
		N = -N; //取反
	}
	m = 0;
	while(N) {
		now = N % R;  //now余数
		if(now <= 9) {  //0 - 9
			ans_09[m++] = '0' + now;
		} else {
			ans_09[m++] = 'A' + now - 10;      //大于10  , 用 'A' 表示 10, 'B' 表示 11 ...
		}
		N /= R ; //除基取余法
	}
	if(m == 0) { //当 m等于0时打印 0
		cout<< 0;
	}
	for(int i = m - 1; i >= 0 ; i--) {
		cout<< ans_09[i] ;
	}
	cout<<endl;//避免多个行号
	return;
}

/*任意一个正整数,如果不是回文数,将该数的 高低位 互换相加  ,若为回文数停止,计数

样例:

349

3
349--->1292--->4213--->7337

*/

int digit_10[1005];
int num_10[1005];  //如果无法判断多少空间 用 vector 等效可变数组
bool judge_10(int x) { //判断回文!!!
	int cnt = 0;
	while(x) {
		digit_10[cnt++] = x % 10;  //取每一位
		x /= 10;
	}
	for(int i = 0; i < cnt / 2; i++) { //头尾判断 , 一半结束
		if(digit_10[i] != digit_10[cnt - 1 - i]) {
			return false;
		}
	}
	return true;
}
int rev_10(int x) { //反转  !!!!!
	int ret = 0;
	while(x) {
		ret = ret*10 + x % 10; //在个位的每次进一 ,变最高位
		x /= 10;
	}
	return ret;
}
void test_10() {
	int n , m;
	cin >> n;  //把每一步得到的数,变换的数存下来
	m = 0;
	num_10[m++] = n;
	while(!judge_10(n)) { //判断回文 ,不是就反转相加 ,保存数组中
		n += rev_10(n);
		num_10[m++] = n;
	}
	cout<< m - 1 <<endl; //输出次数
	for(int i = 0; i < m; i++) {
		if(i != m - 1) {
			cout<< num_10[i] << "--->";
		} else {
			cout<< num_10[i] <<endl;
		}
	}
	return;
}

/*一个机器人礼物 4种指令
 forward x  前进x米
 back x  先后转 然后前进x米
 left x  先左转 然后前进x米
right x  先右转 然后前进x米


输入 指令数
指令...

10
back -9
left 3
left 8
back 15
right 10
right -7
right -3
left 11
right 17
left 3

输出坐标 x y
9 -7
*/
int dx[4] = {0,-1,0,1};   //往后 往左 往右 往前初始化x轴正方向   一定要顺时针或逆时针 好对应左转或右转的变化 
int dy[4] = {1,0,-1,0};
char op[15];  //存放操作指令  forward back  left  right
void test_11() {
	int n,d,x,nowx,nowy; //n 指令数  d 当前方向  更新坐标 x,y    x为命令值
	cin>>n;
	d = 3;  //初始化当前方向x轴正方向   dx[d],dy[d] == (1,0)
	nowx = 0;
	nowy = 0;
	for(int i = 0; i <n; i++) {
		cin>>op>>x;
		if(op[0] == 'b') { //因为命令的首字母不同 ,比较首字母即可
			d = (d + 2) % 4; //往当前方向的反方向走 
		} else if(op[0] == 'l') {
			d = (d + 1) %4;  //向左转  打表逆时针  直接转 90°  d+1 
		} else if(op[0] == 'r') {
			d = (d + 3) %4;  //向右转 == 左转 270°   d+3 
		} //'f' 就不改变方向直接前进
		nowx += dx[d] * x;//单位方向 * 命令值
		nowy += dy[d] * x;
	}
	cout<< nowx <<" "<<nowy<<endl;
	return; 
}

int main() {
	test_11();

	return 0;
}


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值