天天看點

USACO Section 2.2 Runaround Numbers - 又一個枚舉的思想

     題目說的這種數長度最多為9,每位都不重複..并且沒有0..是以如果事先枚舉所有這些數再判斷的話需要枚舉的個數是9!=362880...才30多W~~果斷先枚舉出可能的所有情況~~就按題目要求的判斷下~~枚舉的同時就能保證是有序的~~是以後來的查找輸出就從1開始找到第一個大于輸入的數就ok了...

/*  
ID: zzyzzy12  
LANG: C++  
TASK: runround
*/    
#include<iostream>    
#include<stdio.h>    
#include<string.h>    
#include<math.h>    
#include<algorithm>    
#include<queue>
using namespace std;     
long long n,ans[1000001];
int num,s[10],p;
bool used[10],f[10]; 
bool ok()
{
     int i=1,k,j,num=p; 
     memset(f,0,sizeof(f));
     while (num--)
     { 
            k=i;  
            for (j=1;j<=s[i];j++)
            {
                  k++;
                  if (k==p+1) k=1;    
            } 
            if (f[k]) return false;
            f[k]=true;
            i=k;
     } 
     return true;
}
void search(int n)
{
     int i;
     if (n==p+1)
     { 
           if (ok()) 
           {
                 ans[++num]=0;
                 for (i=1;i<=p;i++) ans[num]=ans[num]*10+s[i];
           }
           return;               
     }
     for (i=1;i<=9;i++) 
     if (!used[i])
     {
           used[i]=true;
           s[n]=i;
           search(n+1);
           used[i]=false;      
     }    
     return;      
}
int main()
{
     freopen("runround.in","r",stdin);
     freopen("runround.out","w",stdout);     
     num=0;
     for (p=1;p<=9;p++)
     {
           memset(used,false,sizeof(used));  
           search(1);
     } 
     cin>>n; 
     int i;
     for (i=1;i<=n;i++) 
        if (ans[i]>n) break;  
     cout<<ans[i]<<endl;
     return 0;   
}