链接:https://ac.nowcoder.com/acm/contest/554/H
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
杨主席这段时间由于要找实习,所以非常焦躁。因为公司的面试都非常的难,杨主席不知道从哪入手。于是他就找了他的学长坑坑询问情况,坑坑告诉他要注重算法的学习,于是就给杨主席出了一个题目看看他算法学的怎么样,这道题是这样的:有N个人排成一排,从1到N按顺序依次编号,现在要执行N次操作,第一次操作让所有的人都蹲下,之后第二次操作让编号是2和2的倍数的人全部站起来,然后第三次操作让编号是3和3的倍数的人全部做相反的动作(站着的人蹲下,蹲下的人站起来),以此类推...,最后第N此操作让编号为N的这个人也做相反的动作。请问N次操作后,从第A个人到第B个人之间(包括A和B这两个数字,且A<B)有多少人是站着的?
输入描述:
输入数据为T组数据(1<=T<=10)。 每组数据输入包含三个数字N,A,B(1<=N<=1000000,1<=A<B<=N)。
输出描述:
对于每组数据,输出一个整数,表示从第A个人到第B个人之间有多少人站着。
示例1
输入
1 5 1 3
输出
2
思路:这道题模拟就可以,但是不能双重循环暴力。
#include<set>
#include<map>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int s[1000005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(s,0,sizeof(s));
int a,b,n;
scanf("%d %d %d",&n,&a,&b);
int c=2;
while(c<=n)
{
int i=1;
while(c*i<=n)
{
if(s[c*i]==0)
s[c*i]=1;
else if(s[c*i]==1)
s[c*i]=0;
//printf("s[%d]=%d\n",c*i,s[c*i]);
i++;
}
c++;
}
int sum=0;
for(int i=a;i<=b;i++)
sum=sum+s[i];
printf("%d\n",sum);
}
return 0;
}