程序设计思维与实践 Week12 作业 (1/2/智能班)

A - 必做题 - 1

给出n个数,zjm想找出出现至少(n+1)/2次的数, 现在需要你帮忙找出这个数是多少?

Input

本题包含多组数据:
每组数据包含两行。
第一行一个数字N(1<=N<=999999) ,保证N为奇数。
第二行为N个用空格隔开的整数。
数据以EOF结束。

Output

对于每一组数据,你需要输出你找到的唯一的数。

Sample Input

5
1 3 2 3 3
11
1 1 1 1 1 5 5 5 5 5 5
7
1 1 1 1 1 1 1

Sample Output

3
5
1

思路

用map统计数字出现的次数,找到超过(n+1)/2的即可。

代码

#include<iostream>
#include<map>
using namespace std;
int main() {
	int n = 0;
//	freopen("in1.txt","r",stdin);
	while(cin>>n) {
		map<long long,int> mp;
		long long tmp;
		bool out = false;
		for(int i=0; i<n; i++) {
			scanf("%lld",&tmp);
			if(!out) {
				if(mp.find(tmp)!=mp.end()) {
					mp[tmp]++;
				} else mp[tmp] = 1;
				if(mp[tmp]>=((n+1)/2)){
					cout<<tmp<<endl;
					out = true;
				} 
			}
		}
	}
	return 0;
}

B - 必做题 - 2zjm被困在一个三维的空间中,现在要寻找最短路径逃生!

空间由立方体单位构成。
zjm每次向上下前后左右移动一个单位需要一分钟,且zjm不能对角线移动。
空间的四周封闭。zjm的目标是走到空间的出口。
是否存在逃出生天的可能性?如果存在,则需要多少时间?

Input

输入第一行是一个数表示空间的数量。
每个空间的描述的第一行为L,R和C(皆不超过30)。
L表示空间的高度,R和C分别表示每层空间的行与列的大小。
随后L层,每层R行,每行C个字符。
每个字符表示空间的一个单元。'#'表示不可通过单元,'.'表示空白单元。
zjm的起始位置在'S',出口为'E'。每层空间后都有一个空行。
L,R和C均为0时输入结束。

Output

每个空间对应一行输出。
如果可以逃生,则输出如下
Escaped in x minute(s).
x为最短脱离时间。

如果无法逃生,则输出如下
Trapped!

Sample Input

3 4 5
S….
.###.
.##..
###.#

#####
#####
##.##
##…

#####
#####
#.###
####E

1 3 3
S##
#E#
###

0 0 0

Sample Output

Escaped in 11 minute(s).
Trapped!

思路

将这些立方体单位转化为图上的点,然后从起点bfs,记录路径,找到终点则停,然后计算路径的长度即可。

代码

#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
char m[33][33][33];
bool visit[33][33][33];
int parent[50001];
int dx[6] = {0, 0,0, 0,1,-1};
int dy[6] = {0, 0,1,-1,0, 0};
int dz[6] = {1,-1,0, 0,0, 0};
struct three {
	int i,j,k;
	three() {
		i = 0;
		j = 0;
		k = 0;
	}
	three(int ii,int jj,int kk) {
		i = ii;
		j = jj;
		k = kk;
	}
	void out() {
		cout<<i<<","<<j<<","<<k<<endl;
	}
	bool operator==(three mm) {
		return i==mm.i&&j==mm.j&&k==mm.k;
	}
};
void initial() {
	for(int i=0; i<=32; i++) {
		for(int j=0; j<=32; j++) {
			for(int k=0; k<=32; k++) {
				m[i][j][k] = '#';
				visit[i][j][k] = 0;
			}
		}
	}
	for(int i=0; i<50001; i++) {
		parent[i] = -1;
	}
}
int main() {
	int L,R,C;
	cin>>L>>R>>C;
	while(L!=0&&R!=0&&C!=0) {
		initial();
		three start,end;
		for(int i=1; i<=L; i++) {
			for(int j=1; j<=R; j++) {
				for(int k=1; k<=C; k++) {
					cin>>m[i][j][k];
					if(m[i][j][k]=='S') start = three(i,j,k);
					if(m[i][j][k]=='E') end = three(i,j,k);
				}
			}
		}
//		start.out();
//		end.out();

		three tmp;
		queue<three> q;
		q.push(start);

		while(q.size()) {
			tmp = q.front();
//			tmp.out();
			int x = tmp.i;
			int y = tmp.j;
			int z = tmp.k;
			q.pop();
			if(tmp==end) break;
			if(visit[x][y][z]) continue;
			visit[x][y][z] = 1;
			for(int i=0; i<6; i++) {
				int tx = x+dx[i];
				int ty = y+dy[i];
				int tz = z+dz[i];
				if(m[tx][ty][tz]!='#') {
					if(visit[tx][ty][tz]) continue;
					parent[tx*900+ty*30+tz] = x*900+y*30+z;
					q.push(three(x+dx[i],y+dy[i],z+dz[i]));
				}
			}
		}
		int ans = 0;
		int x = end.i;
		int y = end.j;
		int z = end.k;
		int tans = start.i*900+start.j*30+start.k;
		while(1) {
			if(parent[x*900+y*30+z]==-1)break;
			if(parent[x*900+y*30+z]==tans) break;
			int tx = parent[x*900+y*30+z]/900;
			int ty = (parent[x*900+y*30+z]-tx*900)/30;
			int tz = (parent[x*900+y*30+z]-tx*900-ty*30);
			x = tx;
			y = ty;
			z = tz;
			ans++;
		}
		if(parent[x*900+y*30+z]==-1) printf("Trapped!\n");
		else {
			printf("Escaped in %d minute(s).\n",ans+1);
		}
		cin>>L>>R>>C;
	}
	return 0;
}

C - 必做题 - 3

东东每个学期都会去寝室接受扫楼的任务,并清点每个寝室的人数。
每个寝室里面有ai个人(1<=i<=n)。从第i到第j个宿舍一共有sum(i,j)=a[i]+...+a[j]个人
这让宿管阿姨非常开心,并且让东东扫楼m次,每一次数第i到第j个宿舍sum(i,j)
问题是要找到sum(i1, j1) + ... + sum(im,jm)的最大值。且ix <= iy <=jx和ix <= jy <=jx的情况是不被允许的。也就是说m段都不能相交。
注:1 ≤ i ≤ n ≤ 1e6 , -32768 ≤ ai ≤ 32767 人数可以为负数。。。。(1<=n<=1000000)
Input
输入m,输入n。后面跟着输入n个ai 处理到 EOF
Output
输出最大和
Sample Input
1 3 1 2 3
2 6 -1 4 -2 3 -2 3
Sample Output
6
8
Hint
数据量很大,需要scanf读入和dp处理。
思路

动态规划问题,在此记录一下转移方程。。。

for(int i=1;i<=m;i++){
			tmp = -inf;
			for(int j=i;j<=n;j++){
				dp[j]=max(dp[j-1] + a[j],b[j-1] + a[j]);
				b[j-1] = tmp;
				tmp = max(tmp,dp[j]);
			}
		}

代码

#include<iostream>
#define inf 1e9
using namespace std;
int a[1000000+10],b[1000000+10],dp[1000000+10];
void initial(){
	for(int i = 0;i < 1000000+10;i++){
		a[i] = 0;
		b[i] = 0;
		dp[i] = 0;
	}
}
int main(){
	int m,n;
//	freopen("in3.txt","r",stdin);
	while(scanf("%d%d",&m,&n)!=EOF){
		initial();
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		int tmp = 0;
		for(int i=1;i<=m;i++){
			tmp = -inf;
			for(int j=i;j<=n;j++){
				dp[j]=max(dp[j-1] + a[j],b[j-1] + a[j]);
				b[j-1] = tmp;
				tmp = max(tmp,dp[j]);
			}
		}
		cout<<tmp<<endl;
	}
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/mopa/p/12935408.html