1. 程式人生 > >E - Enigma Gym - 101889E

E - Enigma Gym - 101889E

傳送門:傳送門

題意:給你一個只含‘?’和數字的字串和一個除數,‘?’處可以填0-9的數,首位不能填0,然後讓你給出能被該除數整除的由字串轉化來的最小的數

思路:簡單的dfs,只有1000*1000的狀態,表示除到多少位餘數是多少的狀態,即可。

附上程式碼:

#include <vector>
#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <cstring>
#include <queue>
#include <list>
#include <cstdio>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <cctype>
#include <sstream>
#include <iterator>
#include <functional>
#include <stdlib.h>
#include <time.h>
#include <bitset>
using namespace std;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
int ggx[1010][1100];
char ch[1010];
char bn[1010];
int num;
int wei;
int dfs(int x,int rem) {
	if (x == strlen(ch)) {
		if (rem) return 0;
		else return 1;
	}
	int zz;
	if (ch[x] != '?') {
		zz = ch[x] - '0' + rem * 10;
		zz = zz%num;
		if (ggx[x + 1][zz] == 0) {
			ggx[x + 1][zz] = 1;
			if (dfs(x + 1, zz)) return 1;
		}
	}
	else {
		for (int i = 0; i < 10; i++) {
			if (x == 0 && i == 0) continue;
			zz = i + rem * 10;
			zz = zz%num;
			if (ggx[x + 1][zz] == 0) {
				ggx[x + 1][zz] = 1;
				bn[x] = i + '0';
				if (dfs(x + 1, zz)) return 1;
			}
		}
	}
	return 0;
}
int dig(int n) {
	int tot = 0;
	while (n > 0) {
		n /= 10;
		tot++;
	}
	return tot;
}
int main(void) {
	scanf("%s %d", ch, &num);
	strcpy(bn, ch);
	memset(ggx, 0, sizeof(ggx));
	wei = dig(num);
	if (wei > strlen(ch)) {
		printf("*\n");
	}
	ggx[0][0] = 1;
	if (dfs(0, 0)) {
		for (int i = 0; i < strlen(ch); i++) {
			printf("%c", bn[i]);
		}
		printf("\n");
	}
	else printf("*\n");
	return 0;
}