【NOIP 2004】 虫食算

【题目链接】

           https://www.luogu.org/problemnew/show/P1092

【算法】

            搜索 + 剪枝

            直接搜索显然会超时,考虑剪枝

            1 : 优化搜索顺序

            2 : 假设我们已经确定了一组(Ai,Bi,Ci),那么,如果(Ai + Bi) mod n 和(Ai + Bi + 1) mod n都不等于Ci,可以剪枝

【代码】

          

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

int i,n,len;
int a[30],ord[30];
char A[30],B[30],C[30];
bool used[30],vis[30];
bool solved;

inline bool ok()
{
    int i;
    for (i = n; i >= 1; i--)
    {
          if (a[A[i]-'A'+1] == -1) continue;
          if (a[B[i]-'A'+1] == -1) continue;    
          if (a[C[i]-'A'+1] == -1) continue;
          if ((a[A[i]-'A'+1] + a[B[i]-'A'+1]) % n == a[C[i]-'A'+1]) continue;
          if ((a[A[i]-'A'+1] + a[B[i]-'A'+1] + 1) % n == a[C[i]-'A'+1]) continue;
          return false;
    }        
    return true;
}
inline void print()
{
    int i;
    for (i = 1; i <= n; i++) printf("%d ",a[i]);
    printf("\n");
}
inline bool check()
{
    int t,b = 0;
    for (i = n; i >= 1; i--)
    {
                t = (a[A[i]-'A'+1] + a[B[i]-'A'+1] + b) % n;
                if (a[A[i]-'A'+1] + a[B[i]-'A'+1] + b >= n) b = 1;
                else b = 0;
                if (a[C[i]-'A'+1] == t) continue;
                else return false;
    }
    if (b) return false;
    else return true;
}
inline void dfs(int dep)
{
    int i;
    if (dep > n)
    {
        if (check())
        {
            solved = true;
            print();    
        }
        return;
    }    
    if (!ok()) return;
    for (i = n - 1; i >= 0; i--)
    {
        if (!used[i])
        {
            a[ord[dep]] = i;
            used[i] = true;
            dfs(dep+1);
            if (solved) return;
            used[i] = false;    
            a[ord[dep]] = -1;
        }        
    } 
}

int main() 
{
        
    memset(a,255,sizeof(a));
    scanf("%d%s%s%s",&n,A+1,B+1,C+1);
    for (i = n; i >= 1; i--)
    {
        if (!vis[A[i]-'A'+1]) 
        {
              ord[++len] = A[i] - 'A' + 1;
              vis[A[i]-'A'+1] = true;
        }
        if (!vis[B[i]-'A'+1]) 
        {
            ord[++len] = B[i] - 'A' + 1;
            vis[B[i]-'A'+1] = true;
        }
        if (!vis[C[i]-'A'+1])
        {
            ord[++len] = C[i] - 'A' + 1;
            vis[C[i]-'A'+1] = true;
        }
    }
    dfs(1);
    
    return 0;
    
}

 

posted @ 2018-07-07 21:57  evenbao  阅读(144)  评论(0编辑  收藏  举报