考研复试上机题目

19北理&北邮

1.字符串

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
char s[maxn];
int f[maxn];
int flag[maxn*2];		// 若flag[i] == -1表示没有f[x]+N==i的x否则使得flag[i]==x 

int main(){
	while(scanf("%s", s)==1) {
		int N = strlen(s);	// 字符串长度 
		int maxlen = 0;		// 答案 
//		思路1.暴力枚举所有子串,在满足条件的子串中寻找最长的,时间复制度为O(n^3) 
		
//		for(int i=0; i<N; i++) {
//			for(int j=i; j<N; j++) {
//				// 当前子串s[i,j]
//				int sum = 0, len = j-i+1;
//				for(int k=i; k<=j; k++) {
//					sum += s[k] - '0';		// 累加数字1 
//				} 
//				if(len%2==0 && sum == len/2 && len>maxlen) {	// 满足条件的子串,并且其长度比之前的都长 
//					maxlen = len;			// 更新 
//				} 
//			}
//		} 
//		思路2.暴力枚举所有子串,利用相邻子串之间的关系,来得到子区间的数字和,时间复制度为O(n^2) 
// 		for(int i=0; i<N; i++) {
// 			int sum = 0; 
//			for(int j=i; j<N; j++) {
//				// 当前子串s[i,j]
//				int len = j-i+1;
//				sum += s[j] - '0'; 
//				if(len%2==0 && sum == len/2 && len>maxlen) {	// 满足条件的子串,并且其长度比之前的都长 
//					maxlen = len;			// 更新 
//				} 
//			}
//		} 
		int b[2] = {0, 0};		// b[0] 表示'0'出现的次数, b[1]表示'1'出现的次数 
		memset(flag, -1, sizeof(flag)); 
		for(int i=0; i<N; i++) {
			b[s[i]-'0']++;		// 统计对应数字出现的次数
			f[i] = b[0]-b[1];	// '0'出现的次数减去'1'出现的次数,其值在[-N, N] 
 			if(flag[f[i]+N]==-1) {	// 说明之前没有出现过这个函数值f[i] 
 				flag[f[i]+N] = i;
			} else {				// 之前出现过函数值f[i], 即当前i和之前保存的那个值构成一个有效解 
			 	if(i - flag[f[i]+N] > maxlen) {	// 如果这个区间更长则更新	
			 		maxlen = i - flag[f[i]+N];
				}
			}
		}

		printf("%d\n", maxlen); 
		
		
		
		
	} 

	return 0;
}


2.成绩排序

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1000+10;
struct Stu{
	int score[5];
	char name[20];
	
} ss[maxn];		// ss保存所有过线同学的信息 

bool cmp(const Stu A, const Stu B) {
	return A.score[4] > B.score[4];		// 根据score[4]进行降序排序 
	
//	if(A.score[4] != B.score[4]) return A.score[4] > B.score[4];
//	return strcmp(A.name, B.name) < 0; 
}
int main(){
	int n;
	scanf("%d", &n);
	int line[5];	// 分数线 
	int cnt = 0;	// 统计过线人数 
	for(int i=0; i<5; i++) scanf("%d", &line[i]);
	for(int i=0; i<n; i++) {
		int score[5];
		score[4] = 0;	// 总分 
		char name[20];
		scanf("%s", name);
		for(int j=0; j<4; j++) {
			scanf("%d", &score[j]);
			score[4] += score[j];	// 累加单科成绩 
		} 
		int ok = 1;	// 标记该同学是否过线
		for(int j=0; j<5; j++) {
			if(score[j]<line[j]) {
				ok = 0;
				break;
			}
		} 
		if(ok) {	// 进入复试名单,拷贝相关信息 
			for(int j=0; j<5; j++) ss[cnt].score[j] = score[j];
			strcpy(ss[cnt].name, name);
			cnt++;	// 过线人数增一 
		}	
	} 
	sort(ss, ss+cnt, cmp);	// 调用系统排序函数 ss[0, cnt)
	for(int i=0; i<cnt; i++) {	// 输出 
		printf("%s", ss[i].name);
		for(int j=0; j<5; j++) printf(" %d", ss[i].score[j]);
		printf("\n");
	} 
	return 0;
}

3.反转二进制

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int main(){
	int n;
	int S[40];		// 栈 
	int top = -1;	// 栈顶指针,指向栈顶元素 
	while(scanf("%d", &n)==1) {		// 接收多组数据,每次接收一组,处理后输出一组 
		top = -1;	// 初始化栈 
		while(n>0) {
			S[++top] = n%2;		// 得到最低位,并放入栈中
			n /= 2;				// 擦除最低位,方便取高位 
		}
		int bi = 1;		// 在转换过程中乘以的数位 
		int sum = 0;	// 转换为十进制的结果 
		while(top>=0) {			// 栈非空 
			sum += S[top--] * bi;	// 累加 
			bi *= 2;				
		}
		printf("%d\n", sum); 
	}
	return 0;
}

4.字母组合

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int main(){
	int n;
	int S[40];		// 栈 
	int top = -1;	// 栈顶指针,指向栈顶元素 
	while(scanf("%d", &n)==1) {		// 接收多组数据,每次接收一组,处理后输出一组 
		top = -1;	// 初始化栈 
		while(n>0) {
			S[++top] = n%2;		// 得到最低位,并放入栈中
			n /= 2;				// 擦除最低位,方便取高位 
		}
		int bi = 1;		// 在转换过程中乘以的数位 
		int sum = 0;	// 转换为十进制的结果 
		while(top>=0) {			// 栈非空 
			sum += S[top--] * bi;	// 累加 
			bi *= 2;				
		}
		printf("%d\n", sum); 
	}
	return 0;
}

19中南大学

1.回文串

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 5000+10;	// 问题规模
char s[maxn]; 
int main(){
	while(scanf("%s", s) == 1) {	// 接收多组数据 
		// 思路1.枚举所有子串,判断当前子串是否为回文串
		int len = strlen(s);	// 字符串长度 
		int ans = 0;	// 统计回文串个数 
//		for(int i=0; i<len; i++) {
//			for(int j=i; j<len; j++) {
//				// 当前子串s[i, j] 
//				int ok = 1;		// 标记当前串是否为回文串 
//				for(int k=0; k<=(j-i)/2; k++) {
//					if(s[i+k]!=s[j-k]) {	// 第k个字符和倒数第k个字符不等,当前不是回文 
//						ok = 0;
//						break;	
//					}
//				} 
//				if(ok) {
//					ans++;
//				}
//			}
//		} 
		// 思路2:枚举所有串的中心点,向两端展开,如果发现不是则当前中心点更长的子串不可能是回文串
		for(int i=0; i<len; i++) {
			int num = 0;	// 向两端展开的长度,即以当前i为中心的回文串个数
			while(i+num<len && i-num>=0 && s[i+num] == s[i-num]) num++;	// 以i为中心的回文串个数(子串长度为奇数)
			ans += num;
			num = 0;
			while(i+1+num<len && i-num>=0 && s[i+1+num] == s[i-num]) // // 以i和i+1为中心的回文串个数(子串长度为偶数)
			ans += num; 
		}
		printf("%d\n", ans);
	}
	return 0;
}

2.挖金子

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 200 + 10;
int a[maxn][maxn];	// 区域金子量
int b[maxn];	// 考虑某一行,b[i]表示[0, i]这个区域中并且选择了i个金子能得到最大值
				// b[i] = max(b[i-2], b[i-3])+a[i] 
int c[maxn];	// c[i]表示第i行能得到的最多金子数量
int d[maxn];	// d[i]表示考虑[0,i]行,选择了第i行能得到最多金子 
int main(){
	int n, m;
	while(scanf("%d%d", &n, &m)==2) {
		for(int i=0; i<n; i++) {
			for(int j=0; j<m; j++) scanf("%d", &a[i][j]);
		}
		for(int i=0; i<n; i++) {
			for(int j=0; j<m; j++) {
				b[j] = max(j-2>=0?b[j-2]:0, j-3>=0?b[j-3]:0) + a[i][j];
			}
			c[i] = max(b[m-1], m-2>=0?b[m-2]:0);		// 第i行能得到的最多金子数量 
			d[i] = max(i-2>=0?d[i-2]:0, i-3>=0?d[i-3]:0) + c[i];
		}
		printf("%d\n",  max(d[n-1], n-2>=0?d[n-2]:0));
	}
	return 0;
}

3.合并排序

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 100 + 10;
int a[maxn], b[maxn], c[maxn]; 
int main(){
	int n, m;
	while(scanf("%d", &n)==1) {
		for(int i=0; i<n; i++) scanf("%d", &a[i]);
		scanf("%d", &m);
		for(int i=0; i<m; i++) scanf("%d", &b[i]);
		int p=0, q=0, k=0;	// 分别扫描线性表a和b
		while(p<n || q<m) {	// 两个表中还有数据 
			if(q>=m || p<n&&a[p]<=b[q]) c[k++] = a[p++];	// 将a表当前数据放入c表
			else c[k++] = b[q++]; 							// 将b表当前数据放入c表
		} 
		for(int i=0; i<k-1; i++) {		// 输出前面k-1个数据 
			printf("%d ", c[i]);
		}
		printf("%d\n", c[k-1]);			// 输出最后一个数据 
	} 
	return 0;
}

4.走路还是坐公交

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int Q[maxn];		// Q表示队列
int front=0, rear=0;	// 队头和队尾指针
int vis[maxn];		// 标记访问数组, vis[i]==0表示i结点没有访问 
int d[maxn];	// d[i]表示i结点层次(距离s的最短路径) 
int fa[maxn];	// fa[i]==j表示i的父节点是j 
int main(){
	int s, e;
	while(scanf("%d%d", &s, &e)==2) {
		front = 0, rear = 0;	// 初始化栈
		memset(vis, 0, sizeof(vis));	// 初始化vis数组表示每个结点都没有访问 
		memset(d, 0, sizeof(d));
		Q[rear++] = s;		// 将初试结点加入队列
		vis[s] = 1;		
		while(front<rear) {		// 队列非空进行BFS搜索 
			int u = Q[front++];	// 出队
			if(u==e) {	// 找到了 
				printf("%d\n", d[u]);
				while(u!=s) {
					printf("%d ", u);
					u = fa[u];
				}
				break;
			} 
			
			// 分别判断三个邻居结点是否访问,如果没有访问加入队尾,并标记访问,更新层次信息 
			if(u*2<maxn && !vis[u*2]) {
				Q[rear++] = u*2;
				d[u*2] = d[u] + 1;	
				vis[u*2] = 1; 
				fa[u*2] = u; 
			}
			if(u+1<maxn && !vis[u+1]) {
				Q[rear++] = u+1;
				d[u+1] = d[u] + 1;
				vis[u+1] = 1;
				fa[u+1] = u;	
			}
			if(u-1>=0 && !vis[u-1]) {
				Q[rear++] = u-1;
				d[u-1] = d[u] + 1;
				vis[u-1] = 1;
				fa[u-1] = u;	
			}		
		}		
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值