杭电OJ题 1592 Half of and a Half 解题报告

本文介绍了一道趣味数学题“HalfofandaHalf”的解题思路与算法实现,通过对问题的逐步拆解和归纳,利用高精度计算方法解决大数运算难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Half of and a Half

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 735    Accepted Submission(s): 319



Problem Description
Gardon bought many many chocolates from the A Chocolate Market (ACM). When he was on the way to meet Angel, he met Speakless by accident.
"Ah, so many delicious chocolates! I'll get half of them and a half!" Speakless said.
Gardon went on his way, but soon he met YZG1984 by accident....
"Ah, so many delicious chocolates! I'll get half of them and a half!" YZG1984 said.
Gardon went on his way, but soon he met Doramon by accident....
"Ah, so many delicious chocolates! I'll get half of them and a half!" Doramon said.
Gardon went on his way, but soon he met JGShining by accident....
"Ah, so many delicious chocolates! I'll get half of them and a half!" JGShining said.
.
.
.
After had had met N people , Gardon finally met Angel. He gave her half of the rest and a half, then Gardon have none for himself. Could you tell how many chocolates did he bought from ACM?
 

Input
Input contains many test cases.
Each case have a integer N, represents the number of people Gardon met except Angel. N will never exceed 1000;
 

Output
For every N inputed, tell how many chocolates Gardon had at first.
 

Sample Input
2
 

Sample Output
7
 
——————————————————————————————————————————
每次减去所有的一半以及一个的一半,可以归纳为Sn = a0+a1+...+an(an = 2^n),由于数据量为1000,即2^1000,需要用高精度计算的方法,先对大数进行分块处理,然后再合并起来,在输出时需要考虑中间数据块如果小于10000,需要在前面补零通过控制符"%04d"来输出


/****************************
 *Name:Half of and a Half.c
 *Tags:ACM water
 *Note:题目思路:每次减去所有的一半以及一个的一半,可以归纳为Sn = a0+a1+...+an(an = 2^n),由于数据量为1000,即2^1000,需要用高精度计算的方法,先对大数进行分块处理,然后再合并起来,在输出时需要考虑中间数据块如果小于10000,需要在前面补零通过控制符"%04d"来输出
 ****************************/

#include <stdio.h>

int main()
{
      int num[1002][500], res[500];
      int n, i, j, c;
      for(i = 0; i < 1002; i++) {
	    for(j = 0; j < 500; j++) {
		  num[i][j] = 0;
	    }
      }  //初始化
      num[0][1] = 1;
      num[0][0] = 1; // 记录数据块数
      for(i = 1; i < 1002; i++) {
	    num[i][0] = num[i-1][0];
	    for(j = 1; j <= num[i-1][0]; j++) {
		  num[i][j] += num[i-1][j]*2;
		  while(num[i][j] >= 10000) {
			if(j+1 > num[i][0]) {
			      num[i][0] = j+1;
			}
			num[i][j+1] = num[i][j]/10000;
			num[i][j] %= 10000;
		  }
	    }
      }  //预处理
      while(scanf("%d", &n) != EOF) {
	    res[0] = num[n][0];
	    for(i = 1; i < 500; i++) {
		  res[i] = 0;
	    }
	    for(i = 0; i <= n; i++) {
		  for(j = 1; j <= num[i][0]; j++) {
			res[j] += num[i][j];
			while(res[j] >= 10000) {
			      if(j+1 > res[0]) {
				    res[0] = j+1;
			      }
			      res[j+1] += (res[j]/10000);
			      res[j] %= 10000;
			}
		  }
	    }
	    printf("%d", res[res[0]]);
	    for(i = res[0]-1; i > 0; i--) {
		  printf("%04d", res[i]);
	    }
	    printf("\n");
      }
      return 0;
}	    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值