【YBT高効率先進】1基本アルゴリズム/ 4深さ優先探索/ 3昆虫食計算

【YBT高効率先進】1基本アルゴリズム/ 4深さ優先探索/ 3昆虫食計算

メモリ制限:256 MiB
制限時間:1000ミリ秒
標準入出力
質問タイプ:従来の
評価方法:テキスト比較

タイトル説明

いわゆるワームを食べる計算とは、元の計算の一部がワームによってかじられることを意味し、残りの数に基づいてかじられる文字を決定する必要があります。簡単な例を見てみましょう。

43#9865#045
8468#6633
44445509678

#記号は、バグによってかじられた数を表します。式によれば、簡単に判断できます。最初の行の2つの数字は5と3で、2番目の行の数字は5です。

ここで、問題に2つの制限を課します。

まず、昆虫の餌の計算の追加のみを検討します。ここでの加算はn-ary加算であり、数式の3つの数値はnビットであり、先行0が許可されます。

第二に、バグはすべての数字をかじります。どの数字が同じかしかわかりません。同じ文字を使用して同じ数字を表し、異なる文字を使用して異なる数字を表します。この数式がn基数の場合、英語のアルファベットの最初のn個の大文字を使用して、数式の0からn-1までのn個の異なる数値を表します。ただし、これらのn文字は必ずしも0からn-1までを順番に表すとは限りません。 。データを入力して、n文字のそれぞれが少なくとも1回表示されるようにします。

BADC
CBDA
DCCC

上記の式は16進式です。明らかに、ABCDが0123を表す限り、この式を成り立たせることができます。あなたの仕事は、与えられた基数の加算式についてn個の異なる文字で表される数を見つけて、加算式が成り立つようにすることです。入力データには、1セットのソリューションのみが含まれることが保証されています。

入力フォーマット

入力の最初の行は、基数を表す整数nです。

2行目から4行目まで、各行には大文字で構成される文字列があり、2つの加数と合計を表します。この文字列の左端と右端にスペースはありません。左から右へ一度は高から低へを表し、ちょうど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;
}

おすすめ

転載: blog.csdn.net/weixin_46975572/article/details/115218224
おすすめ