牛客-蹲着還是站着?(找規律)

題意:
有N個人排成一排,從1到N按順序依次編號,現在要執行N次操作,第一次操作讓所有的人都蹲下,之後第二次操作讓編號是2和2的倍數的人全部站起來,然後第三次操作讓編號是3和3的倍數的人全部做相反的動作(站着的人蹲下,蹲下的人站起來),以此類推…,最後第N此操作讓編號爲N的這個人也做相反的動作。請問N次操作後,從第A個人到第B個人之間(包括A和B這兩個數字,且A<B)有多少人是站着的?
思路1:(模擬/暴力)

#include<bits/stdc++.h>
using namespace std;
const int inf= 0x3f3f3f3f;
typedef long long ll;
int cn[1000000+10];
void init()
{
	memset(cn,-1,sizeof cn); // 1站起來 -1蹲下 
	for(int i=2;i<=1000000;i++)
	{
		for(int j=i;j<=1000000;j+=i)
		cn[j] = -cn[j];
	}
}
int main()
{
	int t;cin>>t;
	init();
	while(t--)
	{
		int n,a,b;
		cin>>n>>a>>b;
		int cnt=0;
		for(int i=a;i<=b;i++) if(cn[i]==1) cnt++;
		cout<<cnt<<endl;
	}
}

思路2(找規律):(用前綴和/樹狀數組可以優化時間複雜度)

(n=1 size=1)
 (n=2 size=2)
 (n=3 size=2)
 (n=4 size=3)
 (n=5 size=2)
 (n=6 size=4)
 (n=7 size=2)
 (n=8 size=4)
 (n=9 size=3)
 (n=10 size=4)
 (n=11 size=2)
 (n=12 size=6)
 (n=13 size=2)
 (n=14 size=4)
 (n=15 size=4)
 (n=16 size=5)
 (n=17 size=2)
 (n=18 size=6)
 (n=19 size=2)
 (n=20 size=6)
 (n=21 size=4)
 (n=22 size=4)
 (n=23 size=2)
 (n=24 size=8)
 (n=25 size=3)
 (n=26 size=4)
 (n=27 size=4)
 (n=28 size=6)

因此 易知 若n爲可開方數 則有奇數個因數

#include <stdio.h>
#include <math.h>
 
int zcs[1000001];
 
int main()
{
    int t, zz;
    int i, j, n, a, b;
    scanf("%d", &t);
    while (t--)
    {
        int count = 0;
        scanf("%d %d %d", &n, &a, &b);
        zz = sqrt(n);
        for (i = 1; i <= zz; i++)
        {
            zcs[i * i] = 1;
        }
        for (i = a; i <= b; i++)
        {
            if (!zcs[i])    count++;
        }
        printf("%d\n", count);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章