程序设计思维与实践 Week12 作业

A - 必做题 - 1
在这里插入图片描述解题思路

  • 因为最后答案唯一,只需要找到出现次数最多的数即可
  • 每次输入一个数a(不需要用数组!用一个变量即可),用数组cnt[a]统计a出现的次数,每次记录max(cnt)和对应的数,最后输出即可。

完整代码

#include<iostream>
#include<cstring>
using namespace std;
int a,cnt[1000000];
int main()
{
	
int n;
while(cin>>n)
{
memset(cnt,0,sizeof(cnt));
int Max=0;
int pos;
for(int i=0;i<n;i++)
	{cin>>a;
	cnt[a]++;
	if(cnt[a]>Max)
		Max=cnt[a],pos=a;
	}
cout<<pos<<endl;
}


}

B - 必做题 - 2
在这里插入图片描述
在这里插入图片描述解题思路

  • 用一个三维数组存储各个位置。
  • 从起始位置开始,bfs,每次向上下左右前后移动,长度+1即可。
  • 到达终点则return,记录长度;如果队列空了还没到,则无法到达。
  • 按要求输出即可。

完整代码

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
char a[31][31][31];
int leng,flag;
int si,sj,sk;//起始点 
int ei,ej,ek;//终点 
int L,R,C;
int reach[31][31][31];

struct nod
{
int x;
int y;
int z;
int len;
};

bool judge(int x,int y,int z)
{
if(x>=0&&x<L&&y>=0&&y<R&&z>=0&&z<C&&reach[x][y][z]==0&&a[x][y][z]!='#')
    {  return 1;
    }else return 0;

} 
queue<nod> q;

6void bfs()
{
	while(!q.empty())
		q.pop();
	nod m,mm,e;
	m.x=si,m.y=sj,m.z=sk,m.z=0;
	e.x=ei,e.y=ej,e.z=ek;
	q.push(m);
	while(!q.empty())
	{
	m=q.front();
	q.pop();
	if(m.x==e.x&&m.y==e.y&&m.z==e.z)
		{leng=m.len;flag=1;return;}
//	if(reach[m.x][m.y][m.z]==1||a[m.x][m.y][m.z]=='#')
//		continue;
	reach[m.x][m.y][m.z]=1;
	//cout<<m.x<<" "<<m.y<<" "<<m.z<<endl;
	
	if(judge(m.x+1,m.y,m.z))
	mm=m,mm.x++,mm.len++,q.push(mm);
	
	if(judge(m.x-1,m.y,m.z))
	mm=m,mm.x--,mm.len++,q.push(mm);
	
	if(judge(m.x,m.y-1,m.z))
	mm=m,mm.y--,mm.len++,q.push(mm);
	
	if(judge(m.x,m.y,m.z-1))
	mm=m,mm.z--,mm.len++,q.push(mm);
	
	if(judge(m.x,m.y+1,m.z))
	mm=m,mm.y++,mm.len++,q.push(mm);
	
	if(judge(m.x,m.y,m.z+1))
	mm=m,mm.z++,mm.len++,q.push(mm);
	}


		


}
int main()
{
std::ios::sync_with_stdio(false);
while(cin>>L>>R>>C)
{
	if(L==0&&R==0&&C==0)
		return 0;
	memset(a,0,sizeof(a));
	memset(reach,0,sizeof(reach));
	flag=0;
	for(int i=0;i<L;i++)
		for(int j=0;j<R;j++)
			for(int k=0;k<C;k++)
				{cin>>a[i][j][k]; 
				if(a[i][j][k]=='S')
					si=i,sj=j,sk=k;
				if(a[i][j][k]=='E')
					ei=i,ej=j,ek=k;
				}
	leng=0;
	bfs();
	if(flag==1)
		cout<<"Escaped in "<<leng<<" minute(s)."<<endl;
	else
		cout<<"Trapped!"<<endl;
}
/*
3 4 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E
*/
}

C - 必做题 - 3

在这里插入图片描述
解题思路

  • 令dp[i][j]表示 前l个数 取i段所能得到的最大的段之和,则对于dp[i][l],可以是将第l个数加入前一个段,也可以让他成为一个新的段;
  • 即dp[i][j]=max(dp[i][j-1]+a[j],dp[i-1][k]+a[j]),
  • 但数据量较大,要进行优化
  • 观察可以发现,dp[i-1][k]可以由上一次循环得到;当前状态dp[i][j]只与dp[i][j-]和max(dp[i-1][j])有关。每次记录max(dp[i-1][j]),即可转为一维

完整代码

#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int a[1000010],d[1000010],fm[1000010];
int main()
{
	std::ios::sync_with_stdio(false);
	int m,n;
	while(cin>>m>>n)
	{
		for(int i=1;i<=n;i++)
			cin>>a[i];
		int ans=0;
		d[0]=0;
		memset(fm,0,sizeof(fm));
		memset(d,0,sizeof(d)); 
		for(int i=1;i<=m;i++)
		{
			ans=-327690000;
			for(int j=i;j<=n;j++)
			{
				d[j]=max(d[j-1]+a[j],fm[j-1]+a[j]);
				fm[j-1]=ans;
				ans=max(ans,d[j]);
			}
		}
		cout<<ans<<endl;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值