• 【GDKOI2012模拟02.01】数字


    想了2个小时。。。都想到数位DP去了,虽然没打(但是我疯了)
    打表找规律。比赛时打了个表发现每九个的D()都是一循环(1~9)
    然后想着怎么做,先打了个暴力然后在想,没想到的是:
    如果x为喜欢的数的话,那么x+22680也是喜欢的数。
    为什么?
    设x=a·D(a),那么x+22680=a·D(a)+22680
    因为D(a)为1~9中的一个,所以D(a)为22680的倍数
    那么a*D(a)+22680=(a+22680/D(a))*D(a),所以没有问题!
    所以我们只需要先预处理一下1~22680的喜欢的数即可。
    每次l~r手动统计答案即可。

    上标:

    #include<cstdio>
    #include<cstring>
    #define ll long long
    #define L 22680
    using namespace std;
    ll l,r,ans=0;
    int T,b[22681],tot=0;
    
    int D(int x) {return (x-1)%9+1;}
    
    int main()
    {
    //	freopen("number.in","r",stdin);
    //	freopen("number.out","w",stdout);
    	for (int i=1;i<=L;i++)
    	{
    		bool bz=0;
    		if (i%9==0 && D(i/9)==9) bz=1;
    		else if (i%8==0 && D(i/8)==8) bz=1;
    		else if (i%7==0 && D(i/7)==7) bz=1;
    		else if (i%6==0 && D(i/6)==6) bz=1;
    		else if (i%5==0 && D(i/5)==5) bz=1;
    		else if (i%4==0 && D(i/4)==4) bz=1;
    		else if (i%3==0 && D(i/3)==3) bz=1;
    		else if (i%2==0 && D(i/2)==2) bz=1;
    		else if (D(i)==1) bz=1;
    		if (bz) b[++tot]=i;
    	}
    	scanf("%d",&T);
    	while (T--)
    	{
    		scanf("%lld %lld",&l,&r);
    		ll fir=l/L*L,sec=0;ans=0;
    		for (int i=1;i<=tot;i++)
    		{
    			sec=fir+b[i];
    			if (sec<l)
    			{
    				sec+=L;
    				if (sec<=r) ans+=(r-sec)/22680+1;
    				continue;
    			}
    			if (sec>r) break;
    			ans+=(r-sec)/22680+1;
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    构建之法阅读笔记06
    构建之法阅读笔记05
    第九周进度条
    团队开发之个人博客九
    团队开发之个人博客八(4月27)
    无人机第二波
    团队开发之个人博客七
    无人机学习第一波
    团队开发之个人博客六
    第八周进度条
  • 原文地址:https://www.cnblogs.com/jz929/p/11817829.html
Copyright © 2020-2023  润新知