2018南京ic G-Pyramid(找规律、多项式求解)

题意:给定图形,问第 n n n个图形中有多少个正三角形。
在这里插入图片描述

思路:暴力找规律打表。代码如下:

	x.push_back(0.0);
	y.push_back(0.0);
	for (int i = 1; i <= 20; i++) {
    
    
		if (i % 2 == 0) {
    
    
			y.push_back(-1.0*sqrt(3.0)*i);
			x.push_back(0.0);
			for (int j = 0; j < (i + 1) / 2; j++) {
    
    
				x.push_back(2.0*(j + 1));
				x.push_back(-2.0*(j + 1));
				y.push_back(-1.0*sqrt(3.0)*i);
				y.push_back(-1.0*sqrt(3.0)*i);
			}
		}
		else {
    
    
			for (int j = 0; j < (i + 1) / 2; j++) {
    
    
				x.push_back(1.0 + 2.0*j);
				x.push_back(-1.0 - 2.0*j);
				y.push_back(-1.0*sqrt(3.0)*i);
				y.push_back(-1.0*sqrt(3.0)*i);
			}
			
		}
		ans = 0;
		for (int j = 0; j < x.size(); j++) {
    
    
			for (int k = j + 1; k < x.size(); k++) {
    
    
				for (int z = k + 1; z < x.size(); z++) {
    
    
					if (ju(k, z, j)) {
    
    
						ans++;
						//cout<<lon(j,k)<<" "<<lon(k,z)<<endl;
						//cout<<j<<" "<<k<<" "<<z<<endl;
					}
				}
			}
		}
		cout << ans << " " << i << endl;
	}

运行之后规律如下:
在这里插入图片描述
然后开始神奇的找规律环节:
首先把每个 f ( x ) f(x) f(x)做差,可以发现
1 , 5 , 15 , 35 , 70 , 126 , 210 1,5,15,35,70,126,210 15153570126210
第一次做差:
4 ,   10 ,   20 ,   35 ,   56 ,   84 4 ,\ 10,\ 20,\ 35,\ 56,\ 84 4, 10, 20, 35, 56, 84
再次做差,第二次做差:
6 , 10 , 15 , 21 , 28 6,10,15,21,28 610152128
第三次做差:(有內味了)
4 , 5 , 6 , 7 4,5,6,7 4567
第四次做差:
1 , 1 , 1 1,1,1 111
所以这个多项式的四阶导数是一个常数,那么就是一个 a n 3 + b n 2 + c n + d an^3+bn^2+cn+d an3+bn2+cn+d的形式,带进式子做解方程就出来了答案:

  • n ≤ 3 n\le3 n3时候进行特判
  • n ≥ 4 n\ge4 n4时候就是 C n + 3 3 C_{n+3}^{3} Cn+33记得用逆元

AC代码:

vector<double> x, y;
int eql(double x, double y) {
    
    
	if (abs(x - y) <= eps)return 1;
	else return 0;
}
double lon(int a, int b) {
    
    
	//cout<<"long"<<(x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])<<endl;
	return (x[a] - x[b])*(x[a] - x[b]) + (y[a] - y[b])*(y[a] - y[b]);
}
int ju(int ax, int ay, int az) {
    
    
	if (eql(lon(ax, ay), lon(ax, az)) && eql(lon(ax, ay), lon(ay, az)))return 1;
	else return 0;
}
int main()
{
    
    
	LL ans = 0;
	//cout << eps << endl;
	//x.push_back(0.0);
	//y.push_back(0.0);
	//for (int i = 1; i <= 20; i++) {
    
    
	//	if (i % 2 == 0) {
    
    
	//		y.push_back(-1.0*sqrt(3.0)*i);
	//		x.push_back(0.0);
	//		for (int j = 0; j < (i + 1) / 2; j++) {
    
    
	//			x.push_back(2.0*(j + 1));
	//			x.push_back(-2.0*(j + 1));
	//			y.push_back(-1.0*sqrt(3.0)*i);
	//			y.push_back(-1.0*sqrt(3.0)*i);
	//		}
	//	}
	//	else {
    
    
	//		for (int j = 0; j < (i + 1) / 2; j++) {
    
    
	//			x.push_back(1.0 + 2.0*j);
	//			x.push_back(-1.0 - 2.0*j);
	//			y.push_back(-1.0*sqrt(3.0)*i);
	//			y.push_back(-1.0*sqrt(3.0)*i);
	//		}
	//		
	//	}
	//	ans = 0;
	//	for (int j = 0; j < x.size(); j++) {
    
    
	//		for (int k = j + 1; k < x.size(); k++) {
    
    
	//			for (int z = k + 1; z < x.size(); z++) {
    
    
	//				if (ju(k, z, j)) {
    
    
	//					ans++;
	//					//cout<<lon(j,k)<<" "<<lon(k,z)<<endl;
	//					//cout<<j<<" "<<k<<" "<<z<<endl;
	//				}
	//			}
	//		}
	//	}
	//	cout << ans << " " << i << endl;
	//}
	int t;
	scanf("%d", &t);
	LL rev2 = quick_mod(2ll, MOD - 2, MOD), rev3 = quick_mod(3ll, MOD - 2, MOD), rev4 = quick_mod(4ll, MOD - 2, MOD);
	LL rev = ((rev2*rev3) % MOD*rev4) % MOD;
	while (t--) {
    
    
		LL n;
		scanf("%lld", &n);
		if (n == 1)printf("1\n"); //cout << 1 << endl;
		else if (n == 2)printf("5\n"); //cout << 5 << endl;
		else if (n == 3)printf("15\n"); //cout << 15 << endl;
		else {
    
    
			ans = (n*(n + 1)) % MOD;
			ans = (ans*(n + 2)) % MOD;
			ans = (ans*(n + 3)) % MOD;
			ans = (ans*rev) % MOD;
			printf("%lld\n", ans);
			//cout << ans << endl;
		}
		
	}
	return 0;
}

おすすめ

転載: blog.csdn.net/weixin_44986601/article/details/111043039