算法笔记-Codeup习题--第四章--未完待续

Codeup 1923 问题 A: 排序

已通过OJ

#include 
#include 
using namespace std;

int main() {
	int n;
	while(scanf("%d", &n)!=EOF) {
		int a[n];
		for(int i=0; i<n; i++) {
			scanf("%d", &a[i]);
		}
		sort(a, a+n);
		for(int i=0; i<n; i++) {
			printf("%d", a[i]);
			if(i<n-1) printf(" ");
		}
		printf("\n");
	}
	return 0;
}

Codeup 1925 问题 B: 特殊排序

已通过OJ

#include 
#include 
using namespace std;

int main() {
	int n;
	while(scanf("%d", &n)!=EOF) {
		int a[n];
		for(int i=0; i<n; i++) {
			scanf("%d", &a[i]);
		}
		sort(a, a+n);
		printf("%d\n", a[n-1]);
		if(n==1) {
			printf("-1");
		} else {
			for(int i=0; i<n-1; i++) {
				printf("%d", a[i]);
				if(i<n-2) printf(" "); 
			}
		}
		printf("\n");	
	}
	return 0;
}

Codeup 1926问题 C: EXCEL排序

遇到的问题:
1.switch case 经常忘记把break加上去,怎么这么健忘?
已通过OJ

#include 
#include 
#include 
using namespace std;
struct Student{
	char num[10];
	char name[10];
	int score;
};

bool cmp1(Student a, Student b) {
	return strcmp(a.num, b.num)<0;
}
bool cmp2(Student a, Student b) {
	if(strcmp(a.name, b.name)!=0) return strcmp(a.name, b.name)<0;
	else return strcmp(a.num, b.num)<0;
}
bool cmp3(Student a, Student b) {
	if(a.score!=b.score) return a.score<b.score;
	else return strcmp(a.num, b.num)<0; 
}

int main() {
	int N, count=0;			//count表示测试用例编号 
	scanf("%d", &N);
	while(N!=0) {
		count++;
		int c;
		scanf("%d", &c);
		Student info[N]; 
		for(int i=0 ;i<N; i++) {
			scanf("%s %s %d", info[i].num, info[i].name, &info[i].score);
		}
		
		switch(c){
			case 1:sort(info, info+N, cmp1);break;
			case 2:sort(info, info+N, cmp2);break;
			case 3:sort(info, info+N, cmp3);
				
		}
		printf("Case %d:\n", count);
		for(int i=0; i<N; i++) {
			printf("%s %s %d\n", info[i].num, info[i].name, info[i].score);
		}
		
		scanf("%d", &N);
	}
	
	
	return 0;
}

Codeup 1927 问题 D: 字符串内排序

已通过OJ

#include 
#include 
#include 
using namespace std;

int main() {
	char str[210];
	while(gets(str)) {
		int length = strlen(str);
		sort(str, str+length);
		printf("%s\n", str);
	}
	
	return 0;
}

Codeup 1978问题 E: Problem B

注意:此题题目没说清楚,输出还包括副对角线的元素之和!
已通过OJ

#include 
#include 
using namespace std;

bool cmp(int a, int b) {					//比较函数 
	return a>b;
}

int main() {
	int m;
	while(scanf("%d", &m)!=EOF) {
		int a[m][m];
		int addin[2*m+2]; 
		for(int i=0; i<m; i++) {			//读入矩阵 
			for(int j=0; j<m; j++) {
				scanf("%d", &a[i][j]);
			}
		}
		int sum_row=0, sum_col=0, k=0;		//其中K表示add[]即和矩阵的位序 
		int sum_first=0, sum_second=0;		//first表示主对角线元素之和, second表示副对角线元素之和 
		for(int i=0; i<m; i++) {			//计算行和 
			for(int j=0; j<m; j++) {
				sum_row += a[i][j];
				sum_col += a[j][i];
				if(i==j) {
					sum_first += a[j][j];
				}
				if(i==m-j-1) {
					sum_second += a[i][j];
				} 
			}
			addin[k++]=sum_row;
			addin[k++]=sum_col;
			sum_row=0;
			sum_col=0;
		}
		addin[k++]=sum_first;
		addin[k++]=sum_second;
		sort(addin, addin+k, cmp); 
		for(int i=0; i<k; i++) {
			printf("%d", addin[i]);
			if(i<k-1) printf(" ");
		} 
		printf("\n");
		
	}
	
	return 0;
}

Codeup 2043 问题 F: 小白鼠排队

已通过OJ

#include 
#include 
#include 
using namespace std;
struct Mouse{
	int weight;
	char color[12];
};

bool cmp(Mouse a, Mouse b) {				//比较函数 
	return a.weight>b.weight;
}



int main() {
	int N;				//表示输入的数据对数
	while(scanf("%d", &N)!=EOF) {
		Mouse info[N];
		for(int i=0 ;i<N; i++) {			//读入数据 
			scanf("%d %s", &info[i].weight, info[i].color);
		}
		sort(info, info+N, cmp);
		for(int i=0; i<N; i++) {
			puts(info[i].color);
		} 
	} 
		
	return 0;
}

Codeup 2069 问题 G: 中位数

已通过OJ

#include 
#include 
using namespace std;

int main() {
	int N;
	scanf("%d", &N);
	while(N!=0){
		int a[N];
		for(int i=0 ;i<N; i++) {				//读入数据 
			scanf("%d", &a[i]);
		}
		sort(a, a+N);
		int mid;								//表示中位数 
		if(N%2==0) {
			mid=(a[(N-1)/2] +a[N/2])/2;
		} else {
			mid=a[(N-1)/2];
		}
		printf("%d\n", mid);
		scanf("%d", &N); 
	}
	
	return 0;
}

Codeup 2080 问题 H: 整数奇偶排序

注意:1.读入的写法,由于没有给定读入的数据有多少组,因此只能按照题目给定的那样去输入。
已通过OJ

#include 
#include 
#include 
using namespace std;
bool cmp(int a, int b) {				//比较函数 
	return a>b;
}

int main() {
	int a[10];
	while(cin>>a[0]>>a[1]>>a[2]>>a[3]>>a[4]>>a[5]>>a[6]>>a[7]>>a[8]>>a[9]) {
		int odd[10], even[10];			//分别表示奇数序列和偶数序列
		int j=0, k=0;					//j和k分别表示奇数序列和偶数序列的位序 
		for(int i=0; i<10; i++) {
			if(a[i]%2==0) {
				even[k++]=a[i];
			} else {
				odd[j++]=a[i];
			}
		} 
		sort(odd, odd+j, cmp);
		sort(even, even+k);
		for(int i=0; i<j; i++) {
			printf("%d ", odd[i]);
		}
		for(int i=0; i<k; i++) {
			printf("%d ", even[i]);
		}
		printf("\n");
	}
	
	return 0;
}

Codeup 2088 问题 I: 排名

已通过OJ

#include 
#include 
#include 
using namespace std;
struct Student{
	char id[25];
	int score;
	int pass;								//1表示通过,0表示不通过 
}; 

bool cmp(Student a, Student b) {
	if(a.score!=b.score) return a.score>b.score;
	else return strcmp(a.id, b.id)<0;
}

int main() {
	int N;
	scanf("%d", &N);
	while(N!=0){
		Student info[N];
		int M;								//表示题数 
		scanf("%d", &M);
		int base;							//表示输入的分数线 
		scanf("%d", &base);
		int full_mark[M+1];
		for(int i=1; i<=M; i++) {			//读入每题的分值 
			scanf("%d", &full_mark[i]);
		}
		int sum=0, k, num;						//sum表示每位学生的总分数,K表示做对的题的总数, num表示序号 
		int count=0;							//计数通过分数线的人数 
		for(int i=0; i<N; i++) {
			scanf("%s %d", &info[i].id, &k);
			for(int j=0; j<k; j++) {
				scanf("%d", &num);
				sum += full_mark[num];
			}
			info[i].score=sum;
			if(sum>=base) {
				info[i].pass=1;
				count++; 
			} 
			sum=0; 
		} 
		printf("%d\n", count);
		sort(info, info+N, cmp);
		for(int i=0; i<N; i++) {
			if(info[i].pass==1) {
				printf("%s %d\n", info[i].id, info[i].score);
			}
		}
		
		scanf("%d", &N);
	}
	return 0;
}

4.2递归

Codeup 1907问题 A: 吃糖果

简单的递归调用,类似斐波那契数列,分治法解决。

#include 
int plan(int n) {
	if(n==1) {			//递归出口 
		return 1;
	} else if(n==2) {
		return 2;
	}
	return plan(n-1)+plan(n-2);		//递归调用 
}

int main() {
	int k;
	while(scanf("%d", &k)!=EOF) {
		int count=plan(k);
		printf("%d\n", count);
	}
	
	return 0;
} 

Codeup 2018问题 B: 数列

已通过OJ

#include 
int fib(int n) {
	if(n==1 || n==2) {
		return 1;
	}
	return fib(n-1)+fib(n-2);
}

int main() {
	int m, n;
	int i,j;
	scanf("%d", &m);
	while(m--) {
		scanf("%d", &n);
		int a[20]={0};
		for(i=1; i<=2*n-2; i++) {
			a[i]=fib(i);
		}
		for(i=1; i<=n; i++) {
			for(j=(n-i)*2; j>0; j--) {		//每行开头的空格 
				printf(" ");
			}
			for(j=0; j<2*i-1; j++) {
				printf("%d", a[j]);
				if(j<2*i-2) printf(" ");
			}
			printf("\n");
		}
		
	}
	return 0;
}

总结:1.对于题目要求的输出格式,一定要找好与输入数字,及行,空格个数的规律,一定不能找错!
2.注意输出的数字之间有空格!
3.思考问题要灵活,对于这样一个三角形的数字,其实都是最后一行的数字集合的子集,也就是说,每次调用fib函数计算数列的时候保存在数组中到时候输出即可,且初始化为零,这样刚好解决了每行开头都是零的问题。

Codeup 2044 问题 C: 神奇的口袋

思路:1.要思考怎样才能穷尽种类,考虑把这些体积存入一个数组中,然后从0号位置开始枚举,即调用递归函数,看这个数字能否可以与下一个数字相加后等于40,若等于则令计数++,若小于40,则递归调用该函数,即令该和加上前面读入数组的下一个位置值,直到可以判别。
2.分而治之,一定要思考如何把这个问题分解成小问题。

#include 
int g[30];
int count, n;
void recur(int index, int sum) {
	sum += g[index];
	if(sum==40) count ++;
	else if(sum<40) {
		for(int i=index+1; i<n; i++) {
			recur(i, sum);
		}
	}
}

int main() {
	while(scanf("%d",&n)!=EOF) {
		count =0;
		for(int i=0; i<n; i++) {
			scanf("%d", &g[i]);
		}
		for(int i=0; i<n; i++) {
			recur(i, 0);
		}
		printf("%d\n", count);
	} 
}

Codeup 2046 问题 D: 八皇后

问题总结:1.这个问题就是书上的关于八皇后的放置问题,或者用直接枚举,或者用回溯。
2.对全排列的递归还不太熟悉,需要多加思考。

#include 
#include 
using namespace std;

int digit[10], a[93]={0};
bool hashtable[10]={false};
int n=8, j=0, b;

void generateP(int index) {
	if(index==n+1) {
		bool flag=true;
		for(int i=1; i<=n; i++) {
			for(int j=i+1; j<=n; j++) {
				if(abs(i-j)==abs(digit[i]-digit[j])) {
					flag=false;
				}
			}
		}
		if(flag==true) {
			j++;
			if(j==b) {
				for(int i=1; i<=8; i++) {
					printf("%d", digit[i]);
				}
				printf("\n");
			}
		}
		return;
	}
	for(int x=1; x<=n; x++) {
		if(hashtable[x]==false) {
			digit[index]=x;
			hashtable[x]=true;
			generateP(index+1);
			hashtable[x]=false;
		}
	}
}

int main() {
	int n;
	scanf("%d", &n);
	while(n--){
		scanf("%d", &b);
		generateP(1);
		j=0;
	}
	return 0;
}

你可能感兴趣的:(算法笔记之Codeup习题)