EOJ3532. 热河路

单点时限: 2.0 sec

内存限制: 256 MB

没有人在热河路谈恋爱,
总有人在天亮时伤感
如果年轻时你没来过热河路,
那你现在的生活是不是很幸福
——李志《热河》

奔跑。跌倒。奔跑。

热河路有一家开了好多年的理发店,不管剪什么样的发型,你只要付五块钱。现在我们来到了热河路。

我们可以将其抽象成一个如下的序列:

110100100010000100000……

请你找出这个无穷序列中指定位置上的数字。

输入格式

第一行一个正整数 n (1≤n≤1500000),表示询问次数。

接下来的 n 行,每行一个正整数 ai (1≤ai≤10^9),ai 表示在序列中的位置。

输出格式

输出 n 行,每行为一个 0 或 1,表示该序列第 ai 位上的数字。

样例

input

4
3
14
7
6

output

0
0
1
0

解法一:(直接模拟,一般会超时):

#include <iostream>
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
class SingleJob {
	public:
		int seq;

};
int main() {
	int jobs, temp;
	SingleJob J[1500000];
	
	// 输入
	cin >> jobs;
	for(int i = 0; i < jobs; i++) {
		cin >> J[i].seq;
	}

	// 输出
	for(int i = 0; i < jobs; i++) {
		int level=0;	// 当前段位0的个数
		int loops=1;	// 当前小节正在读第loops个数字
		for(int pos=1; pos<=J[i].seq; pos++)	// 
		{
			if(level == loops || level==0 ){
				temp = 1;
				level++;
				loops = 1;
			}
			else{
				temp = 0;
				loops++;
			}
		}
		cout << temp <<  endl;
	}
	
	return 0;
}

解法二:Hash方式模拟(缺点是定义数组导致栈空间消耗巨大,在不同的环境下可能会爆栈)

#include <iostream>
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
class SingleJob {
	public:
		int seq;
};

const int Max = 1e9;
bool HashTable[Max]={false};
int main() {
    int jobs, temp;
    SingleJob J[1500000];
    //输入
	cin >> jobs;
	for(int i = 0; i < jobs; i++) {
		cin >> J[i].seq;
	}

    int level = 0;   
    for(int i = 1;i <= Max;i+=level++) {
        HashTable[i] = 1;
    }
    //输出
	for(int i = 0; i < jobs; i++) {
        printf("%d\n", HashTable[J[i].seq]);
    }
    return 0;
}

解法三:折中方案(优化了一下,使用set<int>集合,每获得一个"1"的位置就记入该集合):

这么做能极大地缓解栈空间的压力,省去了一个 10^9 大小的bool型数组。

#include <iostream>
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
class SingleJob {
	public:
		int seq;

};

int main() {
	int jobs, temp;
	SingleJob J[1500000];
	set<int> HashTable;  
	
	// 输入
	scanf("%d", &jobs);
	for (int i = 0; i < jobs; i++) {
		scanf("%d", &J[i].seq);
	}

	int level = 0;
	for (int i = 1; i <= 1e9+1; i += level++) {
		HashTable.insert(i);
	}
	// 输出
	for (int i = 0; i < jobs; i++) {
		temp = (HashTable.find(J[i].seq) !=  HashTable.end()) ? 1:0;
		printf("%d\n", temp);
	}
	return 0;
}

这里有个坑:如果把 scanf 和 printf 用 cin和cout 代替,会导致

Time limit exceeded on test 10 错误

这个问题的导致原因与 cin和cout方法的一些额外开销有关,不是本题的重点。知道一下cin和cout相对而言确实会慢一点就可以了。

附:三种不同解法的时空开销

至于你问我 “为什么不用找规律的解法” 。

我的回答是:

.

就不!ovo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谦谦青岫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值