Ducci Sequence

題目描述:對於一個n元組(a1,a2,......an),可以對於每個數求出它和下一個數的差的絕對值,得到一個新的n元組(|a1-a2|,|a2-a3|,......|an-a1|)。重複這個過程,得到的序列稱爲Ducci序列,例如:(8,11,2,7)->(3,9,5,1)->(6,4,4,2)->(2,0,2,4)->(2,2,2,2)->(0,0,0,0)。也有的序列最終會循環。輸入n元組(3<=n<=15),你的任務是判斷它最終變成0還是循環。輸入保證最多1000步就會變成0或者循環。

這一題比較搞笑,我最開始想複雜了,首先我把一個n元組轉換成唯一的一個string,比如(8,11,2,7)轉換成"8+11+2+7",然後對於每次轉換的n元組用set存儲起來,然後判斷每一次計算產生的新的n元組產生的字符串是否已經產生過,若產生過則爲“LOOP”。很遺憾的是,這種做法超時了。

然後我就一直思考怎麼能夠最快的,判斷計算產生的新的n元組以前是否產生過,可惜的是多次嘗試都是超時。後來重新審題發現一個關鍵,就是Ducci序列最終一定會是循環,或者是“0”序列。並且測試用例都是在1000次中就可以得到結果,所以可以採取最直接的方法,在1000次的循環中,判斷新的n元組是否爲“0”n元組,否則就是循環。實際在本題中,循環200次就足夠了。。。我這裏用了vector,我想直接用數組應該會更快一點。

代碼如下(vs2012運行通過):

// 1594.cpp : 定義控制檯應用程序的入口點。
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>

using namespace std;

vector<int> trans(vector<int> a)
{
    vector<int> b;
    for(int i=0;i<a.size();i++)
    {
        b.push_back(abs(a[i]-a[(i+1)%a.size()]));
    }
    return b;
}

bool isZero(vector<int> a)
{
    for(int i=0;i<a.size();i++)
    {
        if(a[i]!=0)
            return false;
    }
    return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int T;
    cin>>T;
    for(int i=0;i<T;i++)
    {
        vector<int> data;
        int n;
        cin>>n;
        for(int j=0;j<n;j++)
        {
            int num;
            cin>>num;
            data.push_back(num);
        }
		bool flag = false;
        for(int m=0;m<1000;m++)
        {
            if(isZero(data))
            {
				flag = true;
                cout<<"ZERO"<<endl;
                break;
            }
          
            data = trans(data);
        }
		if(flag==false)
		{
			cout<<"LOOP"<<endl;
		}
    }
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章