记录一下菜鸡写oj的经历

由于为了双创学分,报了学校的一个c语言竞赛实训,虽然大一的时候也学过一点算法(但是后来怕秃头就没学了)。没办法啊,又得重新开始学,然后就做起了老师布置的杭电oj的4道题。分别是1040,1045,1872,2020。这几题的思路其实都很简单,只是我太菜了而已。(代码都是cpp文件)

1、1040
这题就是个简单的冒泡排序,只不过是需要一点点加工而已。根据题目描述,我们是需要先输入测试的组数n,然后再输入n行数据,每一行的第一个数是这一行需要排序的数量(大概就这么个意思吧)。

解题思路:先定义一个n来输入测试组数,然后再定义一个一维数组,数组的大小就是n,即每行测试数据的数量。再定义一个二维数组,来存储n行的所有需要排序的数据。然后就直接冒泡排序就行了。有个需要注意的小问题就是,在输出数组的时候,两个数之间要有空格,但是数组末尾不能有空格,不然无法AC的,oj的题好像都是这样。

代码

#include<iostream>
using namespace std;

/**
*冒泡对一个数组排序 ,升序
*参数:传入的数组,数组的大小n 
*/
void Asc(int a[],int n){
	int i,j,temp;
	for(i = 0;i < n;i ++){
		for(j = 1;j < n - i;j++){
			if(a[j - 1] > a[j]){
				temp = a[j - 1];
				a[j - 1] = a[j];
				a[j] = temp;
			}
		}
	}
}

int main() {
	int n,i,j;
	int a[10]; //每组数据大小 
	int b[10][200];  //存放所有要排序的数据 
	
	cin >> n; //输入测试样例组数
	
	/*输入测试数据*/ 
	for(i = 0;i < n;i++){
		cin >> a[i];
		for(j = 0;j<a[i];j++){
			cin >> b[i][j];
		}
	}
	
	/*排序,再输出*/
	for(i = 0;i<n;i++) {
		Asc(b[i],a[i]);
		for(j = 0;j<a[i];j++){
			/*对空格进行简单的处理*/
			if(j == a[i] - 1){
				cout << b[i][j];
			}else{
				cout << b[i][j] << " ";
			}
		}
		cout << "\n";
	}
	return 0;
}

2、1045
这题是个简单的DFS应用,碉堡的上下左右四个方向都可以发射炮弹,条件是设置的碉堡不能打到其他的碉堡(可以打到墙)。该题的目的是要输入一个城市地图,然后求得可以设置的最大碉堡数。

解题思路:用dfs进行深度优先遍历,从坐标0,0开始遍历,每一个坐标,都要遍历在其上下左右四个方向的其他坐标的内容,判断是否是一个碉堡,如果是个碉堡,返回false。如果是墙,则忽略。如果既不是墙,又满足以上条件,则把该坐标设置为碉堡,计数变量加一,继续递归调用dfs函数。调用后再回退一步,变量也要改回去。直到所有的点都被访问。(用了一个max函数来求两个函数的最大值,还有一个memset函数用来初始化数组,所以要加入对应的库)

代码

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<memory.h>
using namespace std;
#define size 4 //大小最大为4 

/*以下:W代表墙,D代表碉堡*/
char world[size][size];  //城市地图 
int n;
int Count; //用于计数 
int Max = 0; //记录最大值 

/*判断当前位置是否可以放置碉堡*/
bool judge(int x,int y) {
	/*往上寻找*/
	for(int i = x - 1;i >= 0;i--){
		if(world[i][y] == 'D')
			return false;
		if(world[i][y] == 'X')
			break;
	}
	/*往左寻找*/
	for(int i = y - 1;i >= 0;i--){
		if(world[x][i] == 'D')
			return false;
		if(world[x][i] == 'X')
			break;
	}
	/*往下寻找*/
	for(int i = x + 1;i < 4;i++){
		if(world[i][y] == 'D')
			return false;
		if(world[i][y] == 'X')
			break;
	}
	/*往右寻找*/
	for(int i = y + 1;i < 4;i++){
		if(world[x][i] == 'D')
			return false;
		if(world[x][i] == 'X')
			break;
	}
	return true;
}

/*Dfs深度遍历*/
void dfs(){
	Max = max(Count,Max); //记录最大值 
	
	/*枚举所有情况,取最大值*/ 
	for(int i = 0;i<n;i++) {
		for(int j = 0;j<n;j++){
			if(world[i][j] == '.' && judge(i,j)){
				world[i][j] = 'D'; //符合条件,放入碉堡 
				Count ++; 
				dfs();
				/*回溯后,放回原值*/
				world[i][j] = '.';
				Count --;
			}
		}
	}
} 

int main(){
	while(1){
		cin >> n;
		/*如果n为0,则结束循环*/ 
		if(n == 0){
			break;
		}
		
		Count = 0;
		Max = 0;
		memset(world,0,sizeof(world)); //用memset进行数组的初始化 
		for(int i = 0;i<n;i++){
			getchar();  //读取换行符,因为是char型数组 
			for(int j = 0;j< n;j++){
				cin >> world[i][j];
			}
		} 
		dfs();
		cout << Max << "\n";
	}
	return 0;
}

3、1872
这题考的是稳定排序,其实也蛮简单的,但是我因为太不细心了,一直AC不了。(最后还是成功了)具体题意就是,先输入一个数代表有几行数据,然后紧跟着输入这一组数据,每行数据是名字和分数(未排序的)。然后再输入这组数据根据某种算法的排序结果。后面的就不说了。

解题思路:把每行数据用一个结构体表示,结构体内容为名字,分数,还有一个就是该行数据的位置或者序号(应该是一个意思吧)。输入结构体的时候,这个位置的值就等于用于for循环的迭代器的值,具体看代码。然后将这组数据用sort函数排序,排序依据是:降序、数据相等时,位置小的在前。然后就可以判断已经排序好的那组数据,先立两个flag为true。如果在相同的位置,两组数据对应的分数不相同,这明显就是排序错误嘛,立个flag1为false,如果分数相同,位置对应不上,那就是不稳定排序啦。(这个题目描述好像有解释的)。再立flag2为false呗。如果经过上面两个判断,两个flag都还是true的话,那就是正确的稳定排序啦。

代码

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
#define Max 311

/*定义一个结构体存储*/ 
struct node{
	int score;
	char name[60];
	int pos; //当前元素的位置 
}stu[Max];

/*返回sort排序的条件*/ 
bool cmp(node a,node b){
	if(a.score != b.score){
		return a.score > b.score;
	}
	else{
		return a.pos < b.pos;
	}
}

int main() {
	int N;
	char reName[311][60];
	int reScore[311];
	
	while(scanf("%d",&N) != EOF){
		/*待排序数据*/ 
		for(int i = 0;i<N;i++){
			cin >> stu[i].name >> stu[i].score;
			stu[i].pos = i;
		}
		/*已排序数据*/
		for(int i = 0;i<N;i++) {
			cin >> reName[i] >> reScore[i];
		}
		
		/*稳定排序*/
		sort(stu,stu+N,cmp);
		
		int flag1 = 1;
		int flag2 = 1;
		
		/*判断是错误排序还是不稳定排序*/ 
		for(int i = 0;i<N;i++){
			if(stu[i].score != reScore[i]) flag1 = 0;
			if(strcmp(stu[i].name,reName[i]) != 0) flag2 = 0;
		}
		
		/*输出错误排序结果,已经是否是稳定排序,不稳定排序也输出稳定排序结果*/ 
		if(!flag1){
			cout << "Error"  << "\n";
			for(int i = 0;i<N;i++){
				cout << stu[i].name << " " << stu[i].score << "\n";
			}
		}
		else if(!flag2){
			cout << "Not Stable" << "\n";
			for(int i = 0;i<N;i++){
				cout << stu[i].name << " " << stu[i].score << "\n";
			}
		}
		else if(flag1 && flag2){
			cout << "Right" << "\n";
		}
	}
	return 0;
}

4、2020
这题好简单,也没啥好记录的了。就是个加了绝对值运算的冒泡排序。
直接上代码吧:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
#define N 100

int a[N];

/**
*冒泡对一个数组排序 ,降序,用绝对值进行比较 
*/
void Desc(int a[],int n){
	int i,j,temp;
	for(i = 0;i < n;i ++){
		for(j = 1;j < n - i;j++){
			if(abs(a[j - 1]) < abs(a[j])){
				temp = a[j - 1];
				a[j - 1] = a[j];
				a[j] = temp;
			}
		}
	}
}

int main(){
	int n;
	cin >> n;
	while(n != 0){
		/*输入数据*/ 
		for(int i = 0;i<n;i++){
			cin >> a[i];
		}
		
		Desc(a,n); //降序绝对值排序 
		
		/*输出*/ 
		for(int i = 0;i<n;i++){
			if(i == n-1){
				cout << a[i];
			}
			else{
				cout << a[i] << " ";
			}
		}
		cout << "\n";
		cin >> n;
	}
	return 0;
}

博客地址:http://www.xyj123.xyz

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值