题解 P1980 【计数问题】

John_Nash

2016-02-08 20:39:46

Solution

这题是noip2013普及组第一题,难度肯定不大,nlog10n的算法不难想出,这里不再说明。 在真正的比赛中,只要想到能ac的算法就可以,但是在练习中还是要锻炼自己的思维,多想想更优的算法。 不难发现,即使不用计算机,答案也很容易求出,如: n=728,x=7 可以按照这样的思路: 个位7:73个 7,17,...,727 十位7:70个 70~79,170~179,...,670~679 百位7:29个 700~728 答案是172 这样,就不难写出log10n的算法,这是一个巨大的改进! ```cpp #include<iostream> #include<cstdio> using namespace std; int main(){ int n,x,m=1,ans=0; scanf("%d%d",&n,&x); while(m<=n){ int a=n/(m*10),b=n/m%10,c=n%m; //a,b,c为n的三部分,求哪一位x的个数,b就为那一位数,a为b左边的数,c为b右边的数,如求1~728中十位7的个数,则a=7,b=2,c=8 if(x){ if(b>x) ans+=(a+1)*m; //如果b>x,说明有(a+1)*m个x(如求1~728中个位7的个数,则为(72+1)*1=73) if(b==x) ans+=a*m+c+1; //如果b=x,说明有a*m+c+1个x(如求1~728中百位7的个数,则为0*100+28+1=29) if(b<x) ans+=a*m; //如果b<x,说明有a*m个x(如求1~728中十位7的个数,则为7*10个) } else{ //x=0的情况和x!=0的情况有所不同 if(b) ans+=a*m; else ans+=(a-1)*m+c+1; } m*=10; } printf("%d\n",ans); return 0; } ```