HDNOIP201405 Yang Hui triangle, hdnoip201405 Yang Hui
2016.1.27
Question description |
The Yang Hui triangle is a digital triangle like the following: 1 1 1 1 2 1 ...... Now we want to find the number of N numbers in the N row of the Yang Hui triangle which can be divisible by the given prime number p. |
Input |
Integer N and p separated by two spaces in a row |
Output |
Returns an integer that indicates the number of the nth row that can be divisible by the given prime number p. |
Input example |
3 2 |
Output example |
1 |
Other Instructions |
For 60% of data, N ≤ 30, p ≤ 1000, for 80% of data, N ≤ 1000, p ≤ 1000, for 100% of data, N ≤ ^ 9, p ≤ 1000 |
First, we know that it is the Lucas theorem and the modulo of the combination number.
And try it one by one.
# Include <iostream> using namespace std; int a [1005], e, ans; int main () {int n, p, B, ct; scanf ("% d", & n, & p); B = n-= 1; while (B) {a [++ e] = B % p; b/= p ;}for (int I = 0; I <= n; I ++) {B = I; ct = 1; while (B) {if (B % p> a [ct]) {ans + = 1; break;} else {ct ++; B/= p ;}}} printf ("% d", ans );}View Code
Then decisive TLE
Then, based on the symmetry of the Yang Hui triangle, cut half
# Include <iostream> using namespace std; int a [1005], e, ans; int main () {int n, p, B, ct; scanf ("% d", & n, & p); B = n-= 1; while (B) {a [++ e] = B % p; b/= p ;}for (int I = 0; I <(n + 1)/2; I ++) {B = I; ct = 1; while (B) {if (B % p> a [ct]) {ans + = 1; break;} else {ct ++; B/= p ;}} ans * = 2; if (n + 1 & 1) {B = n/2; ct = 1; while (B) {if (B % p> a [ct]) {ans + = 1; break;} else {ct ++; B/= p ;}} printf ("% d", ans );}View Code
And again, TLE
So I think of constructor.
I also thought about State compression.
That is, if one of the binary values is 1, the number of constructed values is greater than n in the p-base system.
# Include <iostream> using namespace std; int a [105], e, ans; int main () {int n, p, B, ct; scanf ("% d", & n, & p); B = n-= 1; while (B) {a [++ e] = B % p; b/= p;} for (int t = E-1; t> = 1; t --) {for (int I = (1 <t)-1; i> = 1; I --) {B = I; ct = a [t + 1]; for (int j = T-1; j> = 0; j --) {if (1 <j & B) ct * = p-1-a [j + 1]; else ct * = a [j + 1] + 1 ;} ans + = ct ;}} printf ("% d", ans );}View Code
After AC, I was excited. I instantly felt that I had the potential to be a god of God.
But I found that other people's code is very short...
We have
When I got calm, I found myself stupid *
Clearly, you can calculate it in turn... You need to know how simple it is to construct a number where p is not equal to 0 according to the Lucas theorem...
I understand the code in an instant.
AC code:
# Include <iostream> using namespace std; int e, ans = 1; int main () {int n, p, B; scanf ("% d", & n, & p); B = n-1; while (B) {ans * = B % p + 1; B/= p;} printf ("% d ", n-ans );}View Code