您的位置:首页 > 其它

UVALive_6843_Volume Control(暴力+标记)

2015-05-07 13:17 204 查看
传送门:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=77250#problem/A

题型:枚举标记

题意:

两个一样的音量调节器,N个档位,组合使用将形成不同的音量,如N=4

1 2 3 4

1 2 3 4

--------> 0 1 2 3 4 6 8 9 12 16 ------> 10个

N范围30000,10000组数据,时限7s。

分析:

考虑数据范围和时间,其实是可以暴力枚举,然后标记所有可能的数然后存起来,最好O(1)查询答案。

然而,组合相乘的最大值为9e+8,不用说int标记了,直接开bool数组也是不允许的,所以需要的技巧就是如何处理空间开销。

在C++中,使用vector开bool,可以使得bool长度为1位,如此就将开销节省了8倍。

也可以开(1/8)*(9e+8)的char数组,char长度为1字节,即8位,那么对此可以模拟记录八个数,用位运算进行查找和存取。

By the way,OJ服务器的计算速度还是比自己电脑快的多的~

代码:

Vector<bool>:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>

using namespace std;

const int M = 30010;

vector<bool> vis(900000010);
int ans[M];

void init(){
vis.clear();
int cnt = 1;
for(int i=1;i<=30000;i++){
int ii = i*i;
for(int j=1;j<=i;j++){
int mul = i*j;
if(!vis[mul]){
vis[mul] = true;
cnt++;
}
}
ans[i] = cnt;
}
//    puts("hrhehe");
}

int main(){
init();
int _;
int n;
while(~scanf("%d",&_)){
while(_--){
scanf("%d",&n);
printf("%d\n",ans
);
}
}
return 0;
}


Char[]:

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
long gmax;
typedef unsigned long long ULL;
const ULL MAX=900000000ll;
unsigned char seive[MAX/8+100];

ULL answers[30001];

void set_pos(ULL val) {
unsigned char v=1;
v=v<<(val & 7);
seive[val>>3]|=v;
}

ULL get_pos(ULL val) {
unsigned char v=1;
v=v<<(val & 7);
return seive[val>>3] & v;
}

int main() {
ULL i,j,k,ans,max,t;
int T,N;

set_pos(0);
ans=1;
for(i=1; i<=30000; i++) {
for(j=i,max=i*i; j<=max; j+=i) {
t=get_pos(j);
if(t==0) {
ans++;
set_pos(j);
}
}
answers[i]=ans;
}
scanf("%d",&T);
for(i=0; i<T; i++) {
scanf("%d",&N);
printf("%u\n",answers
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: