栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Jeopardy of Dropped Balls(模拟+优化)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Jeopardy of Dropped Balls(模拟+优化)

题目链接:Problem - J - Codeforces

题目中文意思:

查内克先生有一个新游戏叫丢球。最初,Chanek先生有一个尺寸为n×m的网格a

每个单元格(x,y)包含一个整数ax,y,表示球移动的方向。

ax,y=1-球将向右移动(下一个单元格为(x,y+1));

ax,y=2-球将移动到底部(下一个单元格为(x+1,y));

ax,y=3-球将向左移动(下一个单元格为(x,y−1)).

每次球离开单元格(x,y),整数ax,y将变为2。查内克先生将从第一排开始,依次在c1、c2、…、ck th(1)上落下k个球≤词≤m) 列。

确定每个球将在哪列结束(球离开网格后的位置)。

分析:看到数据范围后就知道这道题肯定不是暴力模拟,这样必然会TLE,我们需要对朴素做法及进行一定的优化,具体优化方法就是我们用一个数组记录一下每一列自下向上的连续的2的个数,这样我们就可以不把模拟进行完就知道结果了,我们对这个数组进行更新时,不能每次都从最下方开始尝试,容易发现这个数组每次更新不会变小,要么不变要么比原来更大,举个例子,假如flag[5]=3,代表第五列自下向上有3个连续的2,则下次更新flag[5]时,我们可以直接从倒数第四行开始,当遍历到第一个不是2的直接跳出,这样保证了每次更新都是有效更新,那如何用这个数组进行优化呢?比如flag[3]=4,总共有6行,我们现在遍历到第三行第三列,那我们就知道了他接下来都是直接向下,这样就可以省去剩下的模拟过程了,具体实现看代码:

#include
#include
#include
#include
using namespace std;
int flag[1005],mp[1005][1005];
//flag[i]记录的是第i列从下往上数连续的2的个数 
int main()
{
	int n, m, k;
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&mp[i][j]);
	for(int j=m;j>=1;j--)//预处理每一列的自下向上的连续的2的个数 
	{
		int i=n;
		while(i)
		{
			if(mp[i][j]!=2) break;
			flag[j]++; 
			i--;
		}
	}
	int nowx=1,nowy;//当前所在的行和列 
	for(int i=1;i<=k;i++)
	{
		scanf("%d",&nowy);
		nowx=1;
		int fflag=-1;
		while(nowx<=n)
		{
			int t=mp[nowx][nowy];
			mp[nowx][nowy]=2;
			if(nowx+flag[nowy]>n) //代表从当前行开始可以直接下落结束 
			{
				printf("%d ",nowy);//输出下降时所在的列 
				fflag=1;
				break;
			}
			if(t==1) nowy++;
			if(t==2) nowx++;
			if(t==3) nowy--;
		}
		if(fflag==-1) printf("%d ",nowy);//如果最后一行初始时无2,则在while循环中不会输出,注意特判 
		for(int i=1;i<=m;i++)//这两重循环最多执行n*m次,仔细体会 
		{
			while(flag[i] 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/290897.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号