Problem:
C: カニサル暗号

問題

えびちゃんは、ある非負整数 D を「カニサル暗号」で暗号化して得られた文字列 C を与えられました。この暗号は、非負整数を 10 進法で表したときの各数字をある（元と異なるとは限らない）決められた数字で置き換えるものです。異なる数字が同じ数字に置き換えられたり、同じ数字が出現位置によって異なる数字に書き換えられることはありません。

たとえば、この暗号化方式によって 2646 が 0545 になることはありますが、3456 が 1333 になったり 1333 が 3456 になることはありません。

いま、えびちゃんは D を 10^9+7 で割った余りが M になることを教えてもらいました。このとき、D として考えられるものを一つ出力してください。複数考えられる場合はどれを出力しても構いません。ただし、D の先頭には余分な 0 はついていないものとします。

入力形式

M
C

制約

0\leq M < 10^9+7

1\leq |C| \leq 10^5

出力形式

D として考えられる非負整数を一行に出力してください。存在しない場合は -1 を出力してください。

入力例1

2
1000000007

出力例1

1000000009

今回の暗号化方式は、0 を 0 に、1 を 1 に、9 を 7 に置き換えるものでした。

入力例2

3
1000000007

出力例2

-1

入力例3

1
01

出力例3

-1

D の先頭に余分な 0 がついていることはありません。

入力例4

45
1000000023

出力例4

6000000087

1000000052 や 2000000059 なども条件を満たすので、それを出力してもかまいません。

入力例5

0
940578326285963740

出力例5

123456789864197523

Solution in C (judge verdict: Accepted)

#include<stdio.h>
#include<string.h>
#define ll long long
#define MOD 1000000007

//next_permutation
void nexp(ll*a,int cnt){
	int l=cnt-1,r=cnt-1;
	ll t;
	while(--l>=0&&a[l]>a[l+1]);
	if(l>=0){
		while(a[l]>a[r])r--;
		t=a[l];a[l]=a[r];a[r]=t;
	}
	for(l++,r=cnt-1;l<r;l++,r--)t=a[l],a[l]=a[r],a[r]=t;
}

ll a[10]={0,1,2,3,4,5,6,7,8,9};
char s[100010];
ll sum[10];
int main(){
	int r;
	scanf("%d%s",&r,s);
	int n=strlen(s);
	if(n==1&&r==0){
		puts("0");
		return 0;
	}

	ll p10=1;
	for(int i=n-1;i>=0;i--){
		int c=s[i]-'0';
		sum[c]=(sum[c]+p10)%MOD;
		p10=p10*10%MOD;
	}
	
	for(int i=0;i<3628800;nexp(a,10),i++)if(a[s[0]-'0']){
		ll ans=0;
		for(int k=0;k<10;k++)ans=(ans+sum[k]*a[k])%MOD;
		if(ans==r){
			for(int i=0;i<n;i++)printf("%d",a[s[i]-'0']);
			puts("");
			return 0;
		}
	}
	puts("-1");
}