dfs 【XR-2】奇迹——洛谷5440

问题描述:
现有一个八位数,从左往右分别代表年月日,例如20240919,代表2024年9月19日,现将该八位数蒙住几位数,问填入数字之后有几种情况是的日为质数,月+日为质数,年+月+日为质数
输入:
第一行输入一个整数n,表示有几个测试数,之后的n行每行输入一个八位字符串,未知的数用'-'代替
输出:
对于每个测试,输出符合要求的种类数
数据范围:
一共 10 个测试点,记 c,c 为八位字符串中 - 的个数。
对前 9 个测试点,在第 i 个测试点中保证 c=i−1,对 100% 的数据保证 1≤T≤10

问题分析:
本题是很明显的dfs问题,需要搜索所有组合并判断该组合是否合适
代码(这是洛谷dalao Ciyang的代码,写了一点注释,真的很厉害)

#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
int n, a[9], prim[10005], flag[10005], tot;
char tmpc;
int p10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
int yue[] = { 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 };
//以下代码为质因式分解内容,之后会专门发一篇文章讲解

inline void init() {
	flag[1] = 1;
	for (int i = 2; i < 10005; i++) {
		if (!flag[i]) prim[++tot] = i;
		for (int j = 1; j <= tot; j++) {
			if (i * prim[j] >= 10005) break;
			flag[i * prim[j]] = 1;
			if (i % prim[j] == 0) break;
		}
	}
	return;
}

inline int pdzs(int x) {
	if (x < 2) return 0;
	for (int i = 1; i <= tot; i++)
		if (x % prim[i] == 0) return x == prim[i];
	return 1;
}

//以上代码为质因式分解内容,之后会专门发一篇文章讲解

//判断平年闰年,闰年返回1
inline int pdrn(int x) {
	return (x % 4 == 0 && x % 100 != 0) || (x % 400 == 0 && x % 3200 != 0);
}

//开始深搜
int dfs(int nown, int num, int rn, int jy) {
	//8-nown代表现在取得的总位数
	//num代表现在取得的数字
	//rn=1表示闰年,rn=0表示平年
	//jy=1表示大月31天,jy=0表示小月30
	if (nown == 0) {
		//判断年份
		if (num / 10000 == 0) return 0;
		if (rn && pdrn(num / 10000) == 0) return 0;
		//判断年+月+日是否为质数
		return pdzs(num);//此时已经判断了日和月+日
	}
	if (nown == 6) {
		//判断日
		if (num == 0 || num > 31 || !pdzs(num))return 0;
		if (num == 31) jy = 1;
	}
	if (nown == 4) {
		//判断月+日
		if (num < 32 || num>1231 || !pdzs(num)) return 0;
		if (jy == 1 && !yue[num / 100]) return 0;
		if (num / 100 == 2) {
			if (num % 100 > 29)return 0;
			if (num % 100 == 29) rn = 1;  //代表为闰年
		}
	}
	//如果当前位数已经确定那么直接下一层
	if (a[nown] != -1) dfs(nown - 1, a[nown] * p10[8 - nown] + num, rn, jy);
	int res = 0;
	for (int i = 0; i <= 9; i++) res += dfs(nown - 1, i * p10[8 - nown] + num, rn, jy);
	//输出最后的可能数
	return res;
}
char get() {
	char ch = getchar();
	while ((ch < '0' || ch>'9') && ch != '-')ch = getchar();
	return ch;
}

void put(int x) {
	if (x > 9)put(x / 10);
	putchar('0' + x % 10);
	return;
}

int main() {
	init(), cin >> n;
	while (n--) {
		for (int i = 1; i <= 8; i++)tmpc = get(), a[i] = (tmpc == '-' ? -1 : tmpc - '0');
		put(dfs(8, 0, 0, 0));
		putchar('\n');
	}
	return 0;
}

posted @ 2024-09-19 10:25  小明算法嘎嘎猛  阅读(16)  评论(0编辑  收藏  举报