2014蓝桥杯决赛 本科B组 生物芯片

来源:互联网 发布:网络信息安全的概念 编辑:程序博客网 时间:2024/05/02 00:27
标题:生物芯片    X博士正在研究一种生物芯片,其逻辑密集度、容量都远远高于普通的半导体芯片。    博士在芯片中设计了 n 个微型光源,每个光源操作一次就会改变其状态,即:点亮转为关闭,或关闭转为点亮。    这些光源的编号从 1 到 n,开始的时候所有光源都是关闭的。    博士计划在芯片上执行如下动作:    所有编号为2的倍数的光源操作一次,也就是把 2 4 6 8 ... 等序号光源打开    所有编号为3的倍数的光源操作一次, 也就是对 3 6 9 ... 等序号光源操作,注意此时6号光源又关闭了。    所有编号为4的倍数的光源操作一次。    .....    直到编号为 n 的倍数的光源操作一次。    X博士想知道:经过这些操作后,某个区间中的哪些光源是点亮的。【输入格式】3个用空格分开的整数:N L R  (L<R<N<10^15)  N表示光源数,L表示区间的左边界,R表示区间的右边界。【输出格式】输出1个整数,表示经过所有操作后,[L,R] 区间中有多少个光源是点亮的。例如:输入:5 2 3程序应该输出:2再例如:输入:10 3 6程序应该输出:3资源约定:峰值内存消耗 < 256MCPU消耗  < 1000ms请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。注意: main函数需要返回0注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。

这道题一看,10^15的数据,很大,很吓人。
仔细分析:
只要芯片操作的次数是奇数,就会打开。是偶数,就会关闭。
我们求的是打开的,就是说我们求操作的次数是偶数的芯片数。

什么样的芯片操作次数是偶数?
就是因数+1,为什么+1,因为最后那个n也要算一次,而我们求因数是从2开始的。
我们可以得出:

void solve(){//我直接在csdn上写的,写错了请见谅    int ans=0;    for(ll i=n;i<=m;++i){        int tol=0;        for(ll j=2;j<=sqrt(i);++j){            if(i%j==0){                tol+=2;            }            if(j*j==i)--tol;        }        ++tol;        if(tol&1)ans++;    }    cout<<ans<<endl;}

这样的解法,可以水过40%的数据,然后,大数据怎么办?
10^15啊?怎么办?
我们分析,其实因子数都是成对出现的,比如12=2*3*4*6
其实12就是偶数次,所以,其实这些因子数我们都不用算。
因为对芯片操作偶数次还是原样的。
那什么数是奇数次呢?

对了!
就是完全平方数!
10^15以内的完全平方数有多少个?
我不知道。。
但是我知道4000万的平方是10^16,比我们的数据规模还要大!
这个时候,我们就可以在1s之内求解了!
注意,我们求的在n和m以内的完全平方数是ans个,我们的答案是(m-n+1-ans)个。
因为:
直到编号为 n 的倍数的光源操作一次。
题目这句话.。
好了,附代码:

#include<cstdio>#include<iostream>using namespace std;#include<cmath>typedef long long ll;int main(){    ll s,n,m;    cin>>s>>n>>m;        ll e=(ll)(sqrt(m)+1);        ll si=(ll)(sqrt(n));        ll ans=m-n+1;        ll t=0;        for(ll i=si;i<=e;i++){            ll temp=i*i;            if(temp>=n&&temp<=m){                t++;            }        }    cout<<(ans-t)<<endl;    return 0;} 

这个代码通过了蓝桥杯决赛官方给的所有测试组。
另外需要测试组的同学可以下方评论后我私发给你哦!

1 0
原创粉丝点击