uva 12627

题意:开始有1个红气球,每小时后1个红气球会变为3个红气球和1个蓝气球,问k小时后第A行到第B行的气球数。

解:用g(k,i)表示第k小时时,从底部数i行的红气球数。所以ans = g(k,2^k-A+1) - g(k,2^k -B)

k小时情况由4个k-1小时时的情况组成由k1,k2,k3,k4表示

如果i所求的区域包含k1,k2,由于k4部分全部是蓝气球,所以求得是2*(k1中在区域中的) + k3

即 i >= 2^(k-1),则 g(k,i) = 2 *  g(k-1,i-2 ^ (k-1)) + c(i);其他则g(k,i) = g(k-1,i);

其中c(0) = 1,c(i) = 3*c(i-1);

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <stack>
#include <cctype>
#include <string>
#include <malloc.h>
#include <queue>
#include <map>
#include <set>

using namespace std;

const int INF = 0xffffff;
const double esp = 10e-8;
const double Pi = 4 * atan(1.0);
const int maxn =  100001 + 10;
const long long mod =  1000000007;
const int dr[] = {1,0,-1,0,-1,1,-1,1};
const int dc[] = {0,1,0,-1,1,-1,-1,1};
typedef long long LL;

LL gac(LL a,LL b){
    return b?gac(b,a%b):a;
}

long long g(int k,int i){
    if(k == 0){
        if(i >= 1)
            return 1;
        else
            return 0;
    }
    if(i >= 1 << (k-1)){
        long long c = pow(3,k-1)+esp;
        return 2* g(k-1,i- (1<< (k-1))) + c;
    }
    else{
        return g(k-1,i);
    }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("inpt.txt","r",stdin);
   // freopen("output.txt","w",stdout);
#endif
    int t;
    scanf("%d",&t);
    for(int cas = 1;cas <= t;cas++){
        int A,B,k;
        scanf("%d%d%d",&k,&A,&B);
        long long tmp = 1 << k;
        long long a = g(k,tmp-A+1);
        long long b = g(k,tmp-B);
        printf("Case %d: %lld\n",cas,a-b);
    }
    return 0;
}
时间: 2024-10-27 03:15:56

uva 12627的相关文章

uva 12627 - Erratic Expansion(递归求解)

递归的边界条件写的多了--没必要写呢么多的.. 不明白可共同探讨~ #include<cstdio> #include<iostream> #include<cmath> using namespace std; long long dp(int kk,int pos) { int n=kk;int temp=(int)pow(2,n); // printf("%d %d\n",kk,pos); if(kk==0&&pos==1) r

(白书训练计划)UVa 12627 Erratic Expansion(递归+找规律)

题目地址:UVa 12627 这题是先找规律,规律在于对于第k个小时的来说,总是可以分成右下角全是蓝色气球,右上角,左下角与左上角三个一模一样的k-1个小时的气球.这样的话,规律就很清晰了,然后用递归做比较方便... 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <ma

UVA - 12627 Erratic Expansion(奇怪的气球膨胀)(递归)

题意:问k小时后,第A~B行一共有多少个红气球. 分析:观察图可发现,k小时后,图中最下面cur行的红气球个数满足下式: (1)当cur <= POW[k - 1]时, dfs(k, cur) = dfs(k - 1, cur); (2)当cur > POW[k - 1]时, dfs(k - 1, cur) = 2 * dfs(k - 1, cur - POW[k - 1]) + tot[k - 1]; 其中,POW[k - 1]为2^(k  - 1),tot[k - 1]为k-1小时后图中的

UVa 12627 奇怪的气球膨胀(分治)

https://vjudge.net/problem/UVA-12627 题意:一开始有一个红气球.每小时后,一个红气球会变成3个红气球和1个蓝气球,而1个蓝气球会变成4个蓝气球.如图所示分别是经过0,1,2,3,小时后得情况.经过k小时后,第A~B行一共有多少个红气球. 思路:由图分析,每次把图分为四个部分,右下角的部分全为蓝气球,不用去管他,剩下三部分都是一样的并且和前一小时的图形是一样的,这样的话我们可以计算出每个时刻红气球的总数. 既然每次可以分为四部分,那么很明显的就是用分治法来解决.

Uva 12627 Erratic Expansion(递归)

这道题大体意思是利用一种递归规则生成不同的气球,问在某两行之间有多少个红气球. 我拿到这个题,一开始想的是递归求解,但在如何递归求解的思路上我的方法是错误的.在研读了例题上给出的提示后豁然开朗(顺便吐槽一下算法竞赛第二版在这这道题目上(P246)提示写的有问题,g(k,i)=2g(k-1,i-2^(k-1))+c(k-1)  ,他把c(k-1)写成了c(k)...我纠结这个纠结了好久) 根据题目提示,这道题可以用f(k,i)表示k小时后最上边i行的红气球总数 那么我们的答案就可以表示为f(k,b

UVA 12627 Erratic Expansion

#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1<<29; ll k,a,b; ll s[maxn]; ll f(ll i,ll k) { if(i==0) r

UVA - 12627 Erratic Expansion 奇怪的气球膨胀 (分治)

紫书例题p245 Piotr found a magical box in heaven. Its magic power is that if you place any red balloon inside it then, after one hour, it will multiply to form 3 red and 1 blue colored balloons. Then in the next hour, each of the red balloons will multip

(记忆化+暴力)UVA - 12627 Erratic Expansion

题意:一个数列,一开始只有一个1,进行k次操作,每次操作都把数列中原本的数全都翻倍然后追加在数列的后面,形成了一个全新的数列,输出全新数列中l到r的和. 分析:以上的题意是经过转化后的题意,变的非常简单,而不在卡在二维的思维中出不来. 可以看到如果在后半段,就等于前半段对应位置的两倍,可以从最高2^k个数的维护,k不断-1,最终变成维护数列中第一个1,直接返回1即可,形成了一个完美的递归. 1 ll dg(int u ,int d,int k) { 2 if(u==1&&d==1)retu

UVa 12627 (递归 计数 找规律) Erratic Expansion

直接说几个比较明显的规律吧. k个小时以后,红气球的个数为3k. 单独观察一行: 令f(r, k)为k个小时后第r行红气球的个数. 如果r为奇数,f(r, k) = f((r+1)/2, k-1) * 2 如果r为偶数,f(r, k) = f(r/2, k-1) 令g(r, k)为k个小时后前r行红气球的个数. 如果r为偶数,g(r, k) = g(r/2, k-1) * 3; 如果r为奇数,g(r, k) = g(r-1, k) + f(r, k); 因此f和g都可以用递归求解. 1 #inc