【CF 676B Pyramid of Glasses】模拟,递归

题目链接:http://codeforces.com/problemset/problem/676/B

题意:一个n层的平面酒杯金字塔,如图,每个杯子的容量相同。现在往最顶部的一个杯子倒 t 杯酒,求流动结束后有多少个杯子被装满。

思路:每个局部的两代三个杯子的流动过程是一致的,因此可以用递归来模拟求解。

具体为:设add(cur, i, l)执行“往第 i 个杯子倒cur量的酒”,附加信息: i 位于第 l 层。若执行完剩余了surplus量的酒,则往 i 的下一层左右两侧的杯子各倒surplus/2量的酒;若无剩余,则抵达递归基。

关于 i 与它下一层的对应关系:我对所有杯子从1开始逐层从左到右编号,因此 i 的左下为i+l, 右下为i+l+1。

关于surplus的值:按照CF的题解的做法,如果有n层,则把每个杯子的容量记为volume = 2 ^ n份,这样能保证即使到第n层每次的cur也都整数。

维护数组v, 其中v[i] 记录当前第 i 个杯子中已有的酒量,若有剩余,则surplus = cur - (volume - v[i])。

最后统计下所有n*(n+1)/2个杯子中v[i]==volume的个数即可。

 1 #include <cstdio>
 2 #include <cmath>
 3 using namespace std;
 4 const int MAX_N = 10;
 5
 6 int t, n;
 7 int num;
 8 int v[MAX_N*(MAX_N+1)/2 + 1];
 9 int volume;
10 int cnt;
11
12 void add(int cur, int i, int l){
13     if(l > n) return ;
14     if(cur + v[i] <= volume){//最多加满当前的,不会溢出
15         v[i] += cur;
16         return ;
17     }
18     int surplus = cur - (volume - v[i]);//有溢出
19     v[i] = volume;
20     add(surplus/2, i+l, l+1);
21     add(surplus/2, i+l+1, l+1);
22 }
23
24 int main()
25 {
26     scanf("%d%d", &n, &t);
27     num = n*(n+1)/2;
28     volume = pow(2, n);
29     int cur = volume * t;
30     cnt = 0;
31     add(cur, 1, 1);
32      for(int i=1; i<=num; i++){
33          //printf("%d %d\n", i, v[i]);
34          if(v[i] == volume) cnt++;
35      }
36     printf("%d\n", cnt);
37     return 0;
38 }

 

时间: 2024-09-19 09:44:43

【CF 676B Pyramid of Glasses】模拟,递归的相关文章

Codeforces Beta Round #10

点击打开链接cf#10 A 思路:模拟 分析: 1 题目要求找到总共的电脑的消耗.题目明确指出在n个时间段之内电脑都是属于第一种状态,并且如果不是第一种状态只要移动鼠标或按键盘马上变为第一种状态. 2 题目还指出每一组输入都保证L<R,并且Ri-1<Li.那么我们只要每输入一个就处理一个即可. 代码: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm>

::before和::after伪元素的用法

一.介绍 css3为了区分伪类和伪元素,伪元素采用双冒号写法. 常见伪类--:hover,:link,:active,:target,:not(),:focus. 常见伪元素--::first-letter,::first-line,::before,::after,::selection. ::before和::after下特有的content,用于在css渲染中向元素逻辑上的头部或尾部添加内容. 这些添加不会出现在DOM中,不会改变文档内容,不可复制,仅仅是在css渲染层加入. 所以不要用:

【C/C++学院】0906-递归转栈/二叉树实现

递归转栈 用栈实现递归.cpp #include<stack> #include <iostream> using namespace std; int printN(int n) { if (n>0) { cout << n; return printN(n - 1); } } void printNS_shunxu(int n) { stack<int> mystack; AAA: if (n > 0) { mystack.push(n);

N皇后问题

八皇后问题是一个古老而著名的问题,它是回溯算法的典型例题.该问题是十九世纪德国著名数学家高斯于1850年提出的:在8行8列的国际象棋棋盘上摆放着 八个皇后.若两个皇后位于同一行.同一列或同一对角线上,则称为它们为互相攻击. 现在要求使这八个皇后不能相互攻击,即任意两个皇后都不能处于同一行.同一列或同一对角线上,问有多少种摆法. 解题思路 在递归方式中,pos[i]表示第i行的皇后摆在第pos[i]列上.也可以使用循环来模拟递归过程. 实现代码 打印所有摆放方式: #include <iostre

求大神将下面递归算法改为非递归算法,万分感谢

问题描述 求大神将下面递归算法改为非递归算法,万分感谢 public void void processFilePath(String sourceDir) { File file = new File(eachSource); if (file.isDirectory()) { for (File each : file.listFiles()) { processFilePath(each.getAbsolutePath()); } } else if (file.getAbsolutePa

javascript栈和队列详细教程

javascript: 栈 列表是一种最自然的数据组织方式.栈就是和列表类似的一种数据结构,它可以用来解决计算机世界里很多的问题.栈是一种高效的数据结构,因为数据只能在栈顶添加或删除,所以这样的操作很快,而且容易实现.栈的使用遍布程序语言的方方面面,从表达式求值到处理函数调用. 一:对栈的操作 栈是一种特殊列表,栈内的元素只能通过列表的一端访问,这一端被称为栈顶.咖啡厅的一摞盘子是现实世界中最常见的栈的例子.只能从上面取盘子,盘子洗净后,也只能摞在这一摞盘子的最上面.栈被称为一种后入先出(LIF

如何用C语言、Python实现栈及典型应用_C 语言

前言 栈是什么,你可以理解为一种先入后出的数据结构(First In Last Out),一种操作受限的线性表... C实现 借助与C语言中的void指针及函数指针,我们可以实现一个链式通用栈: /* stack.h */ #ifndef _STACK_H_ #define _STACK_H_ typedef struct stackNode { void *value; struct stackNode *next; } stackNode; typedef struct stack { st

第十章 基本数据结构——二叉树

可以参考:http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html 摘要 书中第10章10.4小节介绍了有根树,简单介绍了二叉树和分支数目无限制的有根树的存储结构,而没有关于二叉树的遍历过程.为此对二叉树做个简单的总结,介绍一下二叉树基本概念.性质.二叉树的存储结构和遍历过程,主要包括先根遍历.中根遍历.后根遍历和层次遍历. 1.二叉树的定义 二叉树(Binary Tree)是一种特殊的树型结构,每个节点至多有两棵子树,

UVa 110 Meta-Loopless Sorts (递归&amp;amp;代码模拟&amp;amp;全排列)

110 - Meta-Loopless Sorts Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&page=show_problem&problem=46 Background Sorting holds an important place in computer science. Analyzing and