[YBT 고효율 고급] 기본 알고리즘 1 개 / 4 깊이 우선 탐색 / 3 곤충 먹이 계산
메모리 제한 : 256MiB
시간 제한 : 1000ms
표준 입력 및 출력
질문 유형 : 기존
평가 방법 : 텍스트 비교
제목 설명
소위 벌레 먹기 계산은 원래 계산의 일부가 벌레에 의해 갉아 먹는 것을 의미하며 나머지 숫자를 기반으로 갉아 먹은 문자를 결정해야합니다. 간단한 예를 살펴 보겠습니다.
43 #
9865 # 045 8468 # 6633
44445509678
# 기호는 버그가 갉아 먹은 숫자를 나타냅니다. 공식에 따르면 우리는 쉽게 판단 할 수 있습니다. 첫 번째 행의 두 숫자는 5와 3이고 두 번째 행의 숫자는 5입니다.
이제 문제에 대해 두 가지 제한 사항을 적용합니다.
첫째, 우리는 곤충 식품 계산의 추가만을 고려합니다. 여기에 더하기는 n 항 더하기이며 공식의 세 숫자는 n 비트를 가지며 선행 0이 허용됩니다.
둘째, 버그는 모든 숫자를 갉아 먹습니다. 우리는 어떤 숫자가 동일한지만 알 수 있습니다. 동일한 숫자를 나타 내기 위해 동일한 문자를 사용하고 다른 숫자를 나타 내기 위해 다른 문자를 사용합니다. 이 공식이 n 염기이면, 우리는 공식에서 0에서 n-1까지의 n 개의 다른 숫자를 나타 내기 위해 영어 알파벳의 처음 n 개의 대문자를 사용할 것입니다. 그러나이 n 개의 문자는 반드시 0에서 n-1까지 순차적으로 나타내지는 않습니다. . n 개의 문자가 각각 한 번 이상 표시되도록 데이터를 입력합니다.
BADC
CBDA
DCCC
위의 공식은 16 진수 공식입니다. 분명히 ABCD가 0123을 나타내도록하는 한이 공식을 유지할 수 있습니다. 당신의 임무는 주어진 기본 덧셈 공식에 대해 n 개의 다른 문자로 표시된 숫자를 찾는 것입니다. 입력 데이터에는 하나의 솔루션 세트 만 있습니다.
입력 형식
입력의 첫 번째 줄은 정수 n으로 밑수를 나타냅니다.
두 번째 줄에서 네 번째 줄까지 각 줄에는 대문자로 구성된 문자열이 있으며 두 개의 추가와 합을 나타냅니다. 이 문자열의 왼쪽과 오른쪽 끝에 공백이 없습니다. 왼쪽에서 오른쪽으로 한 번은 높음에서 낮음을 나타내며 정확히 1 비트가 있습니다.
출력 형식
각각 A, B ...로 표시되는 숫자를 나타내는 공백으로 구분 된 n 개의 정수 행을 출력합니다.
견본
샘플 입력
5
ABCED
BDACE
EBBAA
샘플 출력
1 0 3 4 2
데이터 범위 및 팁
데이터의 30 %에 대해 n <= 10을 보장합니다.
데이터의 50 %에 대해 n <= 15를 보장합니다.
100 % 데이터의 경우 1 <= n <= 26을 보장합니다.
아이디어
dfs에서 각 숫자를 오른쪽에서 왼쪽으로
검색하고 숫자
1 을 검색 할 때마다 확인하십시오 . 오른쪽의 모든 숫자가 확인되면 (a + b + g) % n! = c, return 0;
2. If 오른쪽에 불확실한 숫자 가 있습니다. (a + b) % n! = c && (a + b + 1) % n! = c, return 0;
3. 가장 높은 비트이면 a + b + g> = n 또는 a + b> = n, 0 반환;
암호
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int n,tot,num[27];
char str[4][27],zm[27];
bool vis[27],use[27];
bool check()
{
int g=0,a,b,c,i;
for(i=n-1;i>=0;i--)
{
a=num[str[0][i]-'A'];
b=num[str[1][i]-'A'];
c=num[str[2][i]-'A'];
if(a>-1&&b>-1&&c>-1)
{
if(g==-1)
{
if(((a+b)%n!=c&&(a+b+1)%n!=c)||(i==0&&a+b>=n))return 0;
}
else
{
if((i==0&&a+b+g>=n)||((a+b+g)%n!=c))return 0;
g=(a+b+g)/n;
}
}
else g=-1;
}
return 1;
}
bool DFS(int dep)
{
if(dep>tot)return 1;
for(int i=0;i<n;i++)
if(!use[i])
{
num[zm[dep]-'A']=i,use[i]=1;
if(check()&&DFS(dep+1))return 1;
num[zm[dep]-'A']=-1,use[i]=0;
}
return 0;
}
int main()
{
int i,j;
ios::sync_with_stdio(false);
memset(num,-1,sizeof(num));
memset(vis,0,sizeof(vis));
memset(use,0,sizeof(use));
cin>>n>>str[0]>>str[1]>>str[2];
for(i=n-1;i>=0;i--)
{
if(!vis[str[0][i]-'A'])vis[str[0][i]-'A']=1,zm[++tot]=str[0][i];
if(!vis[str[1][i]-'A'])vis[str[1][i]-'A']=1,zm[++tot]=str[1][i];
if(!vis[str[2][i]-'A'])vis[str[2][i]-'A']=1,zm[++tot]=str[2][i];
}
for(DFS(1),i=0;i<n;i++)cout<<num[i]<<' ';
return 0;
}