Timus 1114. Boxes

解决Timus1114.Boxes问题,计算不同颜色球放入盒子的所有可能组合数。使用组合数学方法,给出C#及C++实现方案。
Timus 1114. Boxes 要求计算出将两种颜色的球放到盒子中的各种组合的数目。

1114. Boxes

Time Limit: 0.6 second
Memory Limit: 16 MB

N boxes are lined up in a sequence (1 ≤ N ≤ 20). You have A red balls and B blue balls (0 ≤ A ≤ 15, 0 ≤ B ≤ 15). The red balls (and the blue ones) are exactly the same. You can place the balls in the boxes. It is allowed to put in a box, balls of the two kinds, or only from one kind. You can also leave some of the boxes empty. It's not necessary to place all the balls in the boxes. Write a program, which finds the number of different ways to place the balls in the boxes in the described way.

Input

Input contains one line with three integeres N, A and B separated by space.

Output

The result of your program must be an integer writen on the only line of output.

Sample

inputoutput
2 1 1 9
Problem Source: First competition for selecting the bulgarian IOI team.

解答如下(C#语言):

 1  using  System;
 2 
 3  namespace  Skyiv.Ben.Timus
 4  {
 5     //   http://acm.timus.ru/problem.aspx?space=1 &num=1114
 6     sealed   class  T1114
 7    {
 8       static   void  Main()
 9      {
10         string [] ss  =  Console.ReadLine().Split();
11         ulong  n  =   ushort .Parse(ss[ 0 ]);
12         ulong  a  =   ushort .Parse(ss[ 1 ]);
13         ulong  b  =   ushort .Parse(ss[ 2 ]);
14        Console.WriteLine(F(n, a)  * F(n, b));
15      }
16 
17       static   ulong F( ulong  n,  ulong  m)
18      {
19         ulong  v  =   1 ;
20         for  ( ulong  i  =   1 ; i  <=  n; i ++ ) v  =  v  *  (m  +  i)  /  i;
21         return  v;
22      }
23    }
24  }

这道题就是一个组合数学问题。题目说,你有 N (1 ≤ N ≤ 20) 个盒子,A (0 ≤ A ≤ 15) 个红色的球和 B (0 ≤ B ≤ 15) 个蓝色的球。这些球可以放到盒子里面,也可以不放到盒子里面,一个盒子可以放任意多个球。问总共有多少种不同情形。

由于球可以放到盒子里面,也可以不放到盒子里面,所以红球和盒子总共有 C( N + A, A ) 种不同的情形。同样,蓝球和盒子总共有 C( N + B, B ) 种不同的情形。所以,最终的答案就是 C( N + A, A) * C( N + B, B ) 。这里,C( n, m ) 表示从 n 个不同的物品中任意取出 m 个的组合数,公式是 C( n, m ) = n! / (n - m)! / m!。以上程序中的 F( n, m ) = C( n + m, m)。

要注意的是,当输入为 N = 20,A = 15,B = 15 时,输出是 10549134770590785600,这个数已经大于 263 - 1,所以要使用 ulong 数据类型。如果使用 C/C++ 语言,因为 Timus Online Judge 使用的是 Visual C++ 编译器,所以要使用 unsigned __int64 数据类型。如果 在 Sphere Online Judge 答题的话,因为其编译器是 gcc,所以要使用 unsigned long long 数据类型。C++ 语言的程序如下所示(如果是 gcc 编译器则去掉第 2 行开头的“//”):

 1  #include  < iostream >
 2  // #define __int64 long long
 3 
 4  unsigned __int64 f(unsigned __int64 n, unsigned __int64 m)
 5  {
 6    unsigned __int64 v  =   1 ;
 7     for  (unsigned __int64 i  =   1 ; i  <=  n; i ++ ) v  =  v  *  (m  +  i)  /  i;
 8     return  v;
 9  }
10 
11  int  main()
12  {
13    unsigned __int64 n, a, b;
14    std::cin  >>  n  >>  a  >>  b;
15    std::cout  << f(n, a)  * f(n, b)  <<  std::endl;
16  }

本程序的运行时间如下:

有点奇怪的是,Visual C++ 编译器也可以使用 unsigned long long,但是速度却比使用 unsinged __int64 慢了 15 倍。如上图所示,ID = 2154601 的记录就是使用 unsinged long long,运行时间为 0.015 秒。而 ID = 2135962 的记录使用 unsinged __int64,运行时间为 0.001 秒。不知是什么原因。照理说,__int64 应该和 long long 是一样的。

def split_image(image, tile_size=640): """ 将大图分割为指定尺寸的切片 Args: image: 输入图像(numpy数组) tile_size: 切片尺寸,默认640x640 Returns: tiles: 切片列表,每个元素为(image_tile, x_offset, y_offset) """ height, width = image.shape[:2] tiles = [] # 遍历图像网格 for y in range(0, height, tile_size): for x in range(0, width, tile_size): # 计算当前切片坐标 y1 = y y2 = min(y + tile_size, height) x1 = x x2 = min(x + tile_size, width) # 提取切片并记录偏移量 tile = image[y1:y2, x1:x2] tiles.append((tile, x1, y1)) return tiles # 加载YOLOv8分割模型 model = YOLO('yolov8n-seg.pt') # 请确认模型路径正确 # 读取输入图像 image = cv2.imread('large_image.jpg') # 替换为你的图像路径 original_image = image.copy() # 存储所有检测结果 all_boxes = [] all_scores = [] all_class_ids = [] all_masks = [] # 分割图像为640x640切片 tiles = split_image(image) for tile, x_offset, y_offset in tiles: # 转换为RGB格式 tile_rgb = cv2.cvtColor(tile, cv2.COLOR_BGR2RGB) # 执行推理 results = model(tile_rgb) # 解析当前切片结果 for result in results: if result.masks is not None: # 获取检测结果 boxes = result.boxes.xyxy.cpu().numpy() scores = result.boxes.conf.cpu().numpy() class_ids = result.boxes.cls.cpu().numpy().astype(int) masks = result.masks.data.cpu().numpy() # 调整坐标到原始图像坐标系 boxes[:, [0, 2]] += x_offset boxes[:, [1, 3]] += y_offset # 调整掩码坐标 for mask in masks: # 创建与原图大小相同的全零矩阵 full_mask = np.zeros(original_image.shape[:2], dtype=np.uint8) # 将切片区域的掩码放入正确位置 full_mask[y_offset:y_offset+tile.shape[0], x_offset:x_offset+tile.shape[1]] = mask all_masks.append(full_mask)
03-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值