题目大意
有一个无穷序列如下:
110100100010000100000……
请你找出这个无穷序列中指定位置上的数字。
分析
观察1的位置就会发现有规律。1的位置为:1 2 4 7 11……
所以1的位置可以记录下来。
但是我还是有N次没A!我真%我自己
一堆代码
代码1(70分,纯粹暴力)
不TLE就怪了
#include<iostream>
using namespace std;
int i,m,n,j,k;
int a[1500000];
bool f(int a){
for(j=m=1;m<a;j++)m+=j;
return m==a;
}
int main(){
cin>>n;
for(i=1;i<=n;i++){
cin>>k;
cout<<f(k)<<endl;
}
return 0;
}
代码2(MLE爆0)
#include<iostream>
using namespace std;
int i,m,n,j,k;
int a[1500000];
int s[100000001]; //当初我并不知道数组不能开这么大Orz
bool f(int a){
if(a<=100000000 && s[a]!=2)return s[a];
for(j=m=1;m<a;j++)m+=j;
if(a<=100000000)return s[a]=(m==a);
return m==a;
}
int main(){
cin>>n;
for(i=1;i<=100000000;i++)s[i]=2;
for(i=1;i<=n;i++){
cin>>k;
cout<<f(k)<<endl;
}
return 0;
}
代码3(70分RE)
其实正式比赛会爆0
#include<bits/stdc++.h>
using namespace std;
long long maxx,i,m,n,j,k;
long long f[10000001],a[1500001]; //又是超大的数组
int main(){
f[1]=1;m=1;
scanf("%lld",&n);
for(i=1;i<=n;i++){
scanf("%lld",a+i);
maxx=max(a[i],maxx);
}
m=f[1]=1;
for(i=2;m<=maxx;i++){
f[i]=f[i-1]+m;
m++;
}
for(i=1;i<=n;i++){
j=1;
while(f[j]<a[i])j++;
printf("%d\n",f[j]==a[i]);
}
return 0;
}
代码4(90分没错就是map)
#include<bits/stdc++.h>
using namespace std;
int maxx,i,m,n,j,k;
int a[1500001];
int main(){
map<int,int>p;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",a+i);
maxx=max(a[i],maxx);
}
for(i=1;i<=maxx;i+=m){
p[i]=1;
m++;
}
for(i=1;i<=n;i++)
printf("%d\n",(p[a[i]]==1));
return 0;
}
然而TLE了~~
上期我简单介绍了一下map,今天我要补充一下,map比较慢(原来以为不会TLE的)
代码5(AC bitset)
Wow,用bitset存储0-1的信息真的超爽也。
#include<bits/stdc++.h>
using namespace std;
int maxx,i,m,n,j,k;
int a[1500001];
bitset<100000000>p;//默认都是0
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",a+i);
if(a[i]>maxx)maxx=a[i];
}
for(i=1;i<=maxx;m++,i+=m)
p.set(i);//将i处设置为1
for(i=1;i<=n;i++)
printf("%d\n",p.test(a[i]));//看看a[i]是0是1
return 0;
}
我来解释一下bitset
bitset≈bit+set(众:什么鬼)
bitset的原理是用二进制的位来存储(其实也是1个STL,跟map一样)。用他来存储0-1的情况比用bool省内存多了。那么为什么呢?因为1个字节是8位,一个bool是一字节,自己去换算吧。
附加:bitset的一些用法(福利来了)
定义:
bitset<n>a; //a有n位,皆为0
bitset<n>a(x); //a为unsigned long形x的一个二进制副本
bitset<n>a(s); //a是string对象s中含有的位串的副本
bitset<n>a(s,pos,n);//b是s中从位置pos开始的n个位的副本
操作:
操作 | 解释 |
---|---|
b.any() | b中是否存在置为1的二进制位? |
b.none() | b中不存在置为1的二进制位吗? |
b.count() | b中置为1的二进制位的个数 |
b.size() | b中二进制位的个数 |
b[pos] | 访问b中在pos处的二进制位 |
b.test(pos) | b中在pos处的二进制位是否为1? |
b.set() | 把b中所有二进制位都置为1 |
b.set(pos) | 把b中在pos处的二进制位置为1 |
b.reset() | 把b中所有二进制位都置为0 |
b.reset(pos) | 把b中在pos处的二进制位置为0 |
b.flip() | 把b中所有二进制位逐位取反 |
b.flip(pos) | 把b中在pos处的二进制位取反 |
b.to_ulong() | 用b中同样的二进制位返回一个unsigned long值 |
os << b | 把b中的位集输出到os流 |
福利就到这里,祖师爷我去也~~
总结
好吧,这道“水题”的总结还是得写写
- 数组不要开大了
- map查找数据较慢,不要乱用
- 试试用bitset
- 暴力出奇迹,但暴力效率低
就先到这里吧