The Red Button

清風紫雪發表於2021-03-10

The Red Button

問題

問題描述
  Piegirl終於發現了紅色按鈕,你現在還剩最後一個機會去改變這個結局。這個按鈕下面的電路由n個從0到n-1編號節點組成。為了關閉這個按鈕,這n個節點必須以特定的序列拆解。節點0必須首先拆解,在拆解了節點i後,下一個被拆解的節點必須是(2·i) mod n或(2·i)+1 mod n。最後一個被拆解的節點必須是節點0。節點0必須被拆解兩次,其他節點必須剛好被拆解一次。你的任務是找到一個符合要求的順序並輸出它。如果沒有任何一個順序滿足條件,輸出-1。
 
輸入格式
  包含一個整數n(2<=n<=105)
 
輸出格式
  輸出一個可以拆解所有節點的順序。如果不可能輸出-1。如果有多個可能的順序,輸出任意一個。
 
樣例輸入
資料1
2
資料2
3
資料3
4
資料4
16
樣例輸出
資料1
0 1 0
資料2
-1
資料3
0 1 3 2 0
資料4
0 1 2 4 9 3 6 13 10 5 11 7 15 14 12 8 0
資料規模和約定
  對於15%的資料2<=n<=10
  對於30%的資料2<=n<=20
  對於100%的資料2<=n<=105

解法

一開始的思路是DFS,每個節點最多有兩個方向,可以就走,不能就回溯找另一個方向,這樣數量大之後就會TLE,自測120多就出不來結果

TLE程式碼:

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+10;
int n;
int len;
int dist[maxn];
bool vis[maxn];
bool dfs(int k,int d)
{
    if(d==n-1&&(k*2==n||k*2+1==n))
    {
        dist[d]=k;
        dist[n]=0;
        return true;
    }
    dist[d]=k;
//    cout<<d<<" :"<<k<<endl;
    int ne=(k*2)%n;
    if(vis[ne]==false)
    {
        vis[ne]=true;
        if(dfs(ne,d+1))
            return true;
        vis[ne]=false;
    } 
   
    int nex=(k*2+1)%n;
    if(vis[nex]==false)
    {
        vis[nex]=true;
        if(dfs(nex,d+1))
            return true;
        vis[nex]=false;
    } 
    
    return false;
}

int main()
{
    int i,j;
    cin>>n;
    vis[0]=true;
    if(n&1)
        cout<<"-1"<<endl;
    else 
    {
        if(dfs(0,0))
        {
            for(i=0;i<=n;i++)
            {
                if(i!=0)
                    cout<<" ";
                cout<<dist[i];
            }
        }
        
    }
    return 0;
}

正確解法:

只需標記所有節點一遍即可,第一個走頭無路的點就是終點,第二個走投無路的點是倒數第二個終點。。。。

因此,只需標記完所有節點一次,就可得出結果的倒敘。反序後再加上0,就為最終答案。對於偶數直接輸出-1

 

 正確程式碼:

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+10;
int n;

vector<int> dist;
bool vis[maxn];
void dfs(int k)
{
    vis[k]=true;
    if(!vis[(k*2)%n])
        dfs((k*2)%n);
    if(!vis[(k*2+1)%n])
        dfs((k*2+1)%n);
    dist.push_back(k);
}

int main()
{
    int i,j;
    cin>>n;
    vis[0]=true;
    if(n&1)
        cout<<"-1"<<endl;
    else 
    {
        dfs(0);
        reverse(dist.begin(),dist.end());
        dist.push_back(0);
        for(i=0;i<dist.size();i++)
            cout<<dist[i]<<" ";
        cout<<endl;
    }
    return 0;
}

 

相關文章