杭电 2050 折线分割平面

http://acm.hdu.edu.cn/showproblem.php?pid=2050

其它参考:http://blog.csdn.net/lishuhuakai/article/details/8518245

#include<stdio.h>
int main(){
	int c,n;
	scanf("%d",&c);
	while(c--){
		scanf("%d",&n);
		printf("%d\n",2*n*n-n+1);
	}
	return 0;
}

做题时不必求出通项公式,只要求出递推公式就ok了

#include<stdio.h>
int main(){
    int i,c,n;
    __int64 f[10001];
    scanf("%d",&c);
    f[1] = 2;
    f[2] = 7;
    for(i = 3;i <= 10000;i++)
        f[i] = f[i-1]+4*(i-1)+1;
    while(c--){
        scanf("%d",&n);
        printf("%I64d\n",f[n]);
    }
    return 0;
}

这类题目主要确定交点数

(1)直线分割平面

        当有n-1条直线时,平面最多被分成了f[n-1]个区域。则第n条直线要是切成的区域数最多,就必须与每条直线相交且不能有同一交点。 这样就会得到n-1个交点。这些交点将第n条直线分为n部分,每个部分将原有区域一分为二,所以就增加n个区域,得出递推公式:f[n] = f[n-1] + n;转化为f[n] - f[n-1] = n;再展开两边进行累加(高中经常用的方法),最后得出f[n] = n*(n+1)/2+1

(2)折线分割平面

       当n-1条折线时,区域数为f[n-1]。为了使增加的区域最多,则第n条折线的两边要和n-1条折线的两边相交,每边增加的交点数为2*(n-1),即将第n条折线的每边分为2*(n-1)+1部分,每个部分又将原有区域一分二,所以应增加4*(n-1)+2个区域,但折线相邻的两部分只增加一个区域,所以共增加4*(n-1)+1个区域,得出递推公式:f[n] = f[n-1]+4*(n-1)+1,再用(1)中类似的方法求出通项公式:f[n] = 2n^2-n+1

(3)封闭曲线分平面

        题目大致如设有n条封闭曲线画在平面上,而任何两条封闭曲线恰好相交于两点,且任何三条封闭曲线不相交于同一点,问这些封闭曲线把平面分割成的区域个数。
        当n-1个圆时,区域数为f[n-1].那么第n个圆就必须与前n-1个圆相交,因为每两个圆相交有2个交点,将第n个圆分为两部分,所以新增加交点数为2*(n-1),即增加了2*(n-1)个区域。得出递推公式:f[n] = f[n-1] + 2*(n-1),所以f[n] =n^2-n+2

(4)平面分割空间(hdu1290)

      http://acm.hdu.edu.cn/showproblem.php?pid=1290
       由二维的分割问题可知,平面分割与线之间的交点有关,即交点数决定将新增线划分的数目,从而决定新增的区域数。试想在三维中则是否与平面的交线有关呢?当有n-1个平面时,分割的空间数为f[n-1]。要有最多的空间数,则第n个平面需与前n-1个平面相交,且不能有共同的交线。即最多有n-1 条交线。而这n-1条交线把第n个平面最多分割成g[n-1]个区域。(g[n]为(1)中的直线分平面的个数 )此平面将原有的空间一分为二,则最多增加g[n-1]个空间。得出递推公式:f[n] = f[n-1] + g[n-1](g[n] = n*(n+1)/2+1),所以f[n] = (1*2+2*3+3*4+……(n-1)*n)/2+n+1;设an = (n-1)*n = n^2-n,可求出Sn = n(n+1)(2n+1)/6-n(n+1)/2,把Sn带入f[n]得f[n] =  (n^3+5n)/6+1;

#include<stdio.h>
int main(){
    int n,i;
    __int64 f[1001];
    f[1] = 2;
    f[2] = 4;
    for(i = 3;i <= 1000;i++)
        f[i] = f[i-1]+(i-1)*i/2+1;
    while(scanf("%d",&n) == 1){
        printf("%I64d\n",f[n]);
    }
    return 0;
}

另解:

#include<stdio.h>
int main(){
    int n;
    while(scanf("%d",&n) == 1){
        printf("%d\n",(n*n*n+5*n)/6+1);
    }
    return 0;
}

本题不用64位整数也可以
 

 

 



 



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值