【hihoCoder】第77周《Koch Snowflake》题目分析

1、题目大意:

原题链接:http://hihocoder.com/contest/hiho77/problem/1

上图是著名的Koch雪花,或者叫Koch曲线。它是由一个等边三角形演变出来的。具体做法是——将每条边等分成三段,以中间一段为边长又形成一个等边三角形,再去掉中间那一段,就得到了上图所示的K1。然后无限重复这个过程。

Kn:第n次迭代生成的图形。(n=0,1,2,3….);

Nn:Kn 边的数目,为 34n

S(i,n) : Kn的第i条边(i=1,2,3…Nn);

给定S(i,n),求这条边是第几代产生的。如上图,S(1,0)是第0代产生的;S(2,1)是第1代产生的;S(4,1),也就是K1黄色那条边,是第0代产生的;S(9,2),K2蓝色的边,是第1代产生的。

输入:
第一个数字(T<=1000),表示测试案例个数,接下来有T行,每行两个数i(1<=i<= 109 )和n(0<=n<=1000)。

输出:
T行,每行一个整数。

样例输入:

5
1 0
1 1
2 1
10 2
16 3

样例输出:

0
0
1
2
0

2、解题思路:

假设上图左边是第Kn-1的第i条边,经过一次变换得到Kn的4条边。由此得到两个个等式:
f(4(i-1)+1, n) = f(4(i-1)+4, n) = f(i,n-1)
f(4(i-1)+2, n) = f(4(i-1)+3, n) = n

代码如下:

int f(int i, int n){
    int x = i % 4;
    int y = ceil(i / 4);
    if (n == 0){
        return 0;
    }
    if (x == 2 || x == 3){
        return n;
    }
    else{
        return f(y, n-1);
    }
}

3、解题心得

类似这种题,一看应该是能找到数学规律的题目,可以巧解。但是在这之前我们应该先预先准备足够的测试用例,题目给的显然不够,我们可以自己先暴力多打印几组测试用例,就像下面的:

//-----------------------------------------------------
//All Rights Reserved, Copyright (C) 2015, beyourself
//-----------------------------------------------------
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;

int f(int j, int n){...}

int main(){
    int i, j, k, n;
    vector<int> V[100];
    V[0].push_back(0);
    V[0].push_back(0);
    V[0].push_back(0);
    V[0].push_back(0);
    V[1].push_back(0);
    V[1].push_back(0);
    V[1].push_back(1);
    V[1].push_back(1);
    V[1].push_back(0);
    for (i = 2; i < 5; ++i){
        V[i].push_back(0);
        for (j = 1; j < V[i - 1].size(); ++j){
            for (k = 0; k < 4; ++k){
                if (k == 0 || k == 3){
                    V[i].push_back(V[i - 1][j]);
                }
                else{
                    V[i].push_back(i);
                }
            }//k
        }//j
    }//i


    int cas;
    cin >> cas;
    while (cas--){
        cin >> i >> n;

        int t = i % ((int)pow(4.0,n));
        if (t == 0){
            t = (int)pow(4.0, n);
        }
        if (V[n][t] == f(i, n)){
            cout << "\nRight!\n";
        }
        else{
            cout << "\nWrong!\n";
        }
    }//while
    return 0;
}

这样,将正确结果存在容器V中,将函数f(i,n)的结果与正确答案比对,这样将n从0到4都充分测试一遍,再提交源代码,一次性AC的概率大大提高,不至于多次提交不过,白白罚时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值