蹲着还是站着?(暴力/完全平方数)

链接:https://ac.nowcoder.com/acm/contest/554/H
来源:牛客网

题目描述

杨主席这段时间由于要找实习,所以非常焦躁。因为公司的面试都非常的难,杨主席不知道从哪入手。于是他就找了他的学长坑坑询问情况,坑坑告诉他要注重算法的学习,于是就给杨主席出了一个题目看看他算法学的怎么样,这道题是这样的:有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

可以直接暴力,模拟一遍,然后再从A到B跑一遍就行

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<cmath>
const int maxn=1e5+5;
typedef long long ll;
using namespace std;
int pre[1000005];
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n,a,b,count=0;
		scanf("%d%d%d",&n,&a,&b);
		for(int i=1;i<=n;i++)
		    pre[i]=0;
        for(int i=2;i<=n;i++){
        	int len=1;
        	while(i*len<=n){
        		if(pre[i*len]==0)
        		    pre[i*len]=1;
        		else if(pre[i*len]==1)
        		    pre[i*len]=0;
        		len++;
			}
		}
//		for(int i=1;i<=n;i++)
//		    cout<<pre[i]<<" ";
		for(int i=a;i<=b;i++){
			if(pre[i]==1)
			    count++;
		}
		printf("%d\n",count);
	}
	return 0;
}

然后我们可以发现4,9,16.......这些完全平方数都是蹲着的,想一下每个数n都会在叫到n的时候站起来,另外如果前边有因子的话,也会站起来,如果不是完全平方数,他的两个因子一定都小于n,并且不相等,那么他会变两次,可是如果的完全平方数,他们两个因子相等,就只会变一次,所以他就只会蹲着。

#include <stdio.h>
#include <math.h>
int vis[1000001];
int main(){
    int t, tmp;
    int i, j, n, a, b; 
    scanf("%d", &t);
    while (t--){
        int count = 0;
        scanf("%d %d %d", &n, &a, &b);
        tmp = sqrt(n);
        for (i = 1; i <= tmp; i++)
            vis[i * i] = 1;
        for (i = a; i <= b; i++)
            if (!vis[i])    
                count++;
        printf("%d\n", count);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/red_red_red/article/details/89032250