CSP-J-2012-寻宝

[NOIP2012 普及组] 寻宝 - 洛谷


解题思路:

1.是一道纯模拟题,我们只需要建立一个结构体二维数组即可,结构体中包含两个变量,一个bool flag是否有楼梯,一个是int num表示这个房间号的指示牌数字

2.输入数据后,设置一个书签temp,用来表示当前房间号,然后逐层遍历,加上本层的指示牌数字,sum=sum+a[i][temp].num,在i层要找够a[i][temp].num个楼梯房间后,结束循环,跳到上一层

3.注意在书签移动的过程中约瑟夫问题,形成环状


#include<bits/stdc++.h>
using namespace std;
struct node{
	bool flag;
	int num;
}a[10010][110];
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	for(int j=0;j<=m-1;j++)
	{
		cin>>a[i][j].flag>>a[i][j].num;
	}//将每层每个房间的flag和num输入
	int temp;
	cin>>temp;
	long long sum=0;//统计总指示牌的数字 
	for(int i=1;i<=n;i++)
	{
		sum=sum+a[i][temp].num;//累加每层指示牌的数字
		int ans=a[i][temp].num;//记录本层需要走的楼梯
		int x=a[i][temp].flag;//定义本层楼梯的累加器 
		while(1)
		{
			if(x>=ans)//如果遍历的有楼梯的房间大于等于ans 
			break;
			temp++;
			if(temp>m-1)
			temp=0;//如果超出房间号,回到0号房间 
			x=x+a[i][temp].flag;
		}
	}
	cout<<sum%20123;
	return 0;
}

优化思路:

1.这样我们能拿50分,可以想一下,哪里没有通过呢,有一部分为,如果指示牌的数字过大,即使我们开long long 最后的结果也存储不下,那么就需要在每层加上指示牌的时候,就对20123取模,这样解决了数据溢出问题

2.还有一个超时的问题,当x很大的时候,每层的房间只有m个,是小于100的,那么肯定在约瑟夫问题中,做了很多周期性的无效循环,这部分时间是完全耗掉的,那么怎么处理呢?在刚开始输入的时候,就可以将每层的楼梯房数量都统计下来,这样,利用指示牌数字%本层的楼梯房,即应该走的房间,现在解决最后一个问题,取模的结果是可能为0的,比如当本层共有2个楼梯房,指示牌数字 为382,很明显结果为0,但是不可能不走的,最少要走一个周期,所以加上一个判断,如果结果为0,那么该走的房间=本层的楼梯房数量

#include<bits/stdc++.h>
using namespace std;
struct node{
	bool flag;
	int num;
}a[10010][110];
int b[10010];//统计每层共有多少个楼梯房 
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	for(int j=0;j<=m-1;j++)
	{
		cin>>a[i][j].flag>>a[i][j].num;
		b[i]=b[i]+a[i][j].flag;//统计每层共有多少楼梯房 
	}//将每层每个房间的flag和num输入
	int temp;
	cin>>temp;
	long long sum=0;//统计总指示牌的数字 
	for(int i=1;i<=n;i++)
	{
		sum=(sum+a[i][temp].num)%20123;//累加每层指示牌的数字
		int ans=(a[i][temp].num)%b[i];//记录本层需要走的楼梯
		if(ans==0)//如果需要走的楼梯为0,即走了正好重复的圈数
		ans=b[i];//因为不可能是0,那么就让他走一圈
		int x=a[i][temp].flag;//定义本层楼梯的累加器 
		while(1)
		{
			if(x>=ans)//如果遍历的有楼梯的房间大于等于ans 
			break;
			temp++;
			if(temp>m-1)
			temp=0;//如果超出房间号,回到0号房间 
			x=x+a[i][temp].flag;
		}
	}
	cout<<sum;
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值