未知:六邊形——題解

(接上題,反正是一起做的那麼故事情節也接上吧嘻嘻嘻)
“正好,帶我去一趟天線崖。”
”你確定?!你都說了都要暴雨了,前幾天的暴雨……“
”是啊,你還抱怨整天悶在家裏啥事也沒幹呢,結果就剩下我在刷題而你整天再睡覺。“
因爲山脈的阻隔,所以他們只能乘坐小船到達那裏。
而給他們租小船的人,開出了很高的價錢,但是。
”你們幫我解決一個問題,我就免費帶你們去你們想去的地方。“
他指了指酒館前面做的一個漢子,漢子的桌子上擺着一個很大的六邊形棋盤。
————————————————————————
時間限制: 1S 空間限制:256M
棋盤是由許多個六邊形構成的,共有5種不同的六邊形編號爲1到5,棋盤的生成規
則如下:
1.從中心的一個六邊形開始,逆時針向外生成一個個六邊形。
2.對於剛生成的一個六邊形,我們要確定它的種類,它的種類必須滿足與已生成的相
鄰的六邊形不同。
3.如果有多個種類可以選,我們選擇出現次數最少的種類。
4.情況3下還有多個種類可以選,我們選擇數字編號最小的。
現在要你求第N個生成的六邊形的編號。
輸入格式:
第一行:T,表示數據組數
接下來T行,每行一個數:N,表示第N個六邊形
輸出格式:
共t行,每行一個數,表示第N個數據的答案
樣例輸入:
4
1
4
10
100
樣例輸出:
1
4
5
5
數據範圍:
100%數據滿足
1<=T<=20
1<=N<=10000
30%數據滿足
1<=N<=100
————————————————
今天的模擬都很有意思?!
這道明顯是找規律的題卻意外的不好找規律。
思考一下,恩……大概是六邊形使我們石樂志。
但是大家的普遍打法都是靠六邊形轉換成矩形,然後打表。
我們想一想……
這道題難道真的無規律可循嗎?!
當答案找不到規律時,我們想想能夠導出答案的東西是否有規律。
是啊,如果我們知道每一個六邊形的相鄰情況的話完全模擬就可以解決啊!

這就是規律:
遵從題意,我們從起點開始,按放數字的順序依次編號爲1,2……
接下來,我們知道與1相鄰的有2,3,4,5,6,7
那麼因爲1相鄰着2,所以2相鄰着1
又因爲2肯定相鄰着3
所以與2相鄰有1,3
然而還差四個點爲7,8,9,10

好的上述的內容總結爲三條規律:
對於點i,找到與它所有相鄰的六個點
已知i-1的點所鄰的最大編號的點爲k
1.從1~i-1,如果有與i相鄰的點,就加上
2.i+1一定與i相鄰
3.上述兩步操作完後所得的相鄰點的個數爲n<6,那麼接下來的點分別爲k+0,k+1……直到n==6爲止

其實我們還可以證明這個的正確性(然而再寫下去我的手就抽筋了,證明就交給大家了?)

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int l[10001][7]={0};
int f[10001]={0};
int cnt[6]={0};
int ji[10001]={0};
bool ok[10001]={0};
void chu(){
    for(int i=1;i<=6;i++){
        l[1][i]=i+1;
    }
    ok[1]=1;
    for(int i=1;i<=10000;i++){
        if(ok[i]==1){
            for(int j=1;j<=6;j++){
                int k=l[i][j];
                if(k>10000||ok[k]==1)continue;
                ji[k]++;
                l[k][ji[k]]=i;
                if(ji[k]==6)ok[k]=1;
            }
        }else{
            ji[i]++;
            l[i][ji[i]]=i+1;
            if(ji[i]==6){
                ok[i]=1;
                i--;
                continue;
            }else{
                int hah=0;
                for(int j=ji[i]+1;j<=6;j++){
                    l[i][j]=l[i-1][6]+hah;
                    hah++;
                }
            }
            ji[i]=6;ok[i]=1;
            i--;
        }
    }
    return;
}
bool ha[7];
int main(){
    freopen("hex.in","r",stdin);
    freopen("hex.out","w",stdout);
    chu();
    int t;
    scanf("%d",&t);
    int maxn=1;
    while(t--){
        int n;
        scanf("%d",&n);
        if(f[n]!=0){
            printf("%d\n",f[n]);
            continue;
        }else{
            for(int i=maxn;i<=n;i++){
                memset(ha,0,sizeof(ha));
                for(int j=1;j<=6;j++){
                    if(l[i][j]>10000)continue;
                    ha[f[l[i][j]]]=1;
                }
                int minn=2147483647;
                for(int j=1;j<=5;j++){
                    if(ha[j]==0){
                        minn=min(minn,cnt[j]);
                    }
                }
                for(int j=1;j<=5;j++){
                    if(ha[j]==0&&minn==cnt[j]){
                        f[i]=j;
                        cnt[j]++;
                        break;
                    }
                }
            }
        }
        printf("%d\n",f[n]);
        maxn=max(maxn,n+1);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章