6
最近看了一些ACM的书要吐血了,这题刚看的时候居然有点蒙,现设a+b/c==n, 问题出在n上,就是我想n那么大枚举完a再考虑b, c肯定要超时怎么行呢!然而别忘了一点,就是说n可以很大,可以一直变,但是有一点不变,那就是1~9的排列数,你这些其实只能从1~9的排列里面选出数来,比如随便167385492,那么就是说a取前面几个数,b接着取几个数,剩下的给c,现在的情况就是变得跟n没多大关系了,然后根据限制条件(1)a<n(2)b<c(3)b%c==0可以筛除一大部分数据,就是枚举的时候注意一下技巧。
# include <cstdio> # include <cmath> # include <algorithm> using namespace std; int n, s[10]; int main(){ int i, j, k, a, b, c, ans; scanf("%d", &n); ans=0; for(i=0; i<=8; i++){ s[i]=i+1; } do{ a=0; for(i=0; i<=6; i++){ a=10*a+s[i]; if(a>=n){ break; } b=0;c=0; for(j=i+1; j<=(8-i+1)/2+i; j++){//因为b>c所以b取剩下的数目至少一半。 b=b*10+s[j]; } for(j=(8-i+1)/2+i+1; j<=8; j++){//b取完后剩下的给c c=c*10+s[j]; } if(b>c&&b%c==0&&a+b/c==n){ ans++; } for(k=(8-i+1)/2+i+1; k<=7; k++){//动态改变b,c b=b*10+s[k];c=c-s[k]*(int)pow(10, 8-k); if(b%c==0&&a+b/c==n){ ans++; } } } }while(next_permutation(s, s+9)); printf("%d", ans); return 0; }