ECNU 3532 热河路
链接
https://acm.ecnu.edu.cn/problem/3532
题目
单点时限: 2.0 sec
内存限制: 256 MB
没有人在热河路谈恋爱,
总有人在天亮时伤感
如果年轻时你没来过热河路,
那你现在的生活是不是很幸福
——李志《热河》
奔跑。跌倒。奔跑。
热河路有一家开了好多年的理发店,不管剪什么样的发型,你只要付五块钱。现在我们来到了热河路。
我们可以将其抽象成一个如下的序列:
110100100010000100000……
请你找出这个无穷序列中指定位置上的数字。
输入格式
第一行一个正整数 n (),表示询问次数。
接下来的 n 行,每行一个正整数 ai (), 表示在序列中的位置。
输出格式
输出 n 行,每行为一个 0 或 1,表示该序列第 ai 位上的数字。
样例
input
4
3
14
7
6
output
0
0
1
0
思路
这题数据离谱,就没打算让java做出来,java两种方法一个从倒数第二组就卡,一个从倒数第三组就卡。
所以最后我拿c交的。
去除开头,就是一个数字序列1101001000,拆开是1+10+100+1000,就是1+2+3+4位,每块的第一位才是1,别的都是0,这样就有两种思路,一种是数学方法,(1+i)*i/2 = n-1时,就可以得知此位n为1,第一位需要特殊判断。另外一种就是空间模拟,第一次把1放进去,第二次把10放进去,直接模拟这个序列,控制输出即可。
代码
public static void fun() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 0; i < n; i++) {
int num = sc.nextInt();
if (num == 1) {
System.out.println(1);
} else {
num = (num - 1) << 1;
int use = (int) Math.sqrt(num);
if (use * (use + 1) == num) {
System.out.println(1);
} else {
System.out.println(0);
}
}
}
}
public static void fun2() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int max = 100000010;
boolean[] a = new boolean[max];
int count = 0;
for (int i = 1; i <= max; i += count) {
a[i] = true;
count++;
}
for (int i = 0; i < n; i++) {
int temp = sc.nextInt();
if (a[temp]) {
System.out.println(1);
} else {
System.out.println(0);
}
}
}
#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
int main()
{
int n=0 ;
scanf("%d",&n);
for (int i = 0; i < n; i++) {
int num=0;
scanf("%d",&num);
if (num == 1) {
printf("%d
",1);
} else {
num = (num - 1) << 1;
int use = sqrt(num);
if (use * (use + 1) == num) {
printf("%d
",1);
} else {
printf("%d
",0);
}
}
}
}