ZOJ - 3816 Generalized Palindromic Number

Description

A number that will be the same when it is written forwards or backwards is known as a palindromic number. For example, 1234321 is a palindromic number.

We call a number generalized palindromic number, if after merging all the consecutive same digits, the resulting number is a palindromic number. For example, 122111 is a generalized palindromic number. Because after merging, 122111 turns
into 121 which is a palindromic number.

Now you are given a positive integer N, please find the largest generalized palindromic number less than
N.

Input

There are multiple test cases. The first line of input contains an integer
T
(about 5000) indicating the number of test cases. For each test case:

There is only one integer N (1 <= N <= 1018).

Output

For each test case, output the largest generalized palindromic number less than
N.

Sample Input

4
12
123
1224
1122

Sample Output

11
121
1221
1121
题意:求小于N的回文数,这个数的回文相同的数可以缩成一个数
思路:dfs(l, r, eq):l代表左边侧长度,r代表右边的长度,eq代表是否处于边界,然后在搜索右边匹配左边的同时,枚举k,k代表连续相同的数都匹配左边的个数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long ll;
using namespace std;

char str[50];
int len;
char leftnum[50], rightnum[50];
char ans[50];
ll target;

ll getans(int l, int r) {
	ll ans = 0;
	for (int i = 1; i <= l; i++)
		ans = ans * 10 + leftnum[i];
	for (int i = r; i >= 1; i--)
		ans = ans * 10 + rightnum[i];
	return ans;
}
ll dfs(int l, int r, int eq) {
	ll ans = -1;
	if (l + r - 1 >= len) {
		if (l + r - 1 > len)
			return -1ll;
		ans = getans(l - 1, r);
		if (ans < target)
			return ans;
		return -1ll;
	}

	int m = eq ? str[l] : 9;
	for (int i = m; i >= 0; i--) {
		leftnum[l] = i;
		if ((l == 1 || leftnum[l] != leftnum[l - 1]) && !(l == 1 && i == 0) && !(l+r == len)) {
			for (int k = 1; k + r + l <= len; k++) {
				rightnum[r + k] = i;
				ans = max(ans, dfs(l + 1, r + k, eq && (i == m)));
			}
		}
		else ans = max(ans, dfs(l + 1, r, eq && i == m));
		if (ans  > 0 )
			return ans;
	}
	return ans;
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		scanf("%lld", &target);
		sprintf(str+1, "%lld", target);
		len = strlen(str+1);
		for (int i = 1; i <= len; i++)
			str[i] -= '0';
		printf("%lld\n", dfs(1, 0, 1));
	}
	return 0;
}

时间: 2024-12-06 05:02:14

ZOJ - 3816 Generalized Palindromic Number的相关文章

zoj 3816 Generalized Palindromic Number(暴力枚举)

题目链接:zoj 3816 Generalized Palindromic Number 题目大意:给定n,找一个最大的数x,保证x小于n,并且x为palindromic number 解题思路:枚举前i个放于n相同的数,然后去构造后半部分即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long ll; int

ZOJ - 3816 Generalized Palindromic Number dfs

Generalized Palindromic Number Time Limit: 2 Seconds                                     Memory Limit: 65536 KB A number that will be the same when it is written forwards or backwards is known as a palindromic number. For example, 1234321 is a palind

zoj 3816 Generalized Palindromic Number (根据对称性来搜)

Generalized Palindromic Number Time Limit: 2 Seconds      Memory Limit: 65536 KB A number that will be the same when it is written forwards or backwards is known as a palindromic number. For example, 1234321 is a palindromic number. We call a number

[ACM] ZOJ 3816 Generalized Palindromic Number (DFS,暴力枚举)

Generalized Palindromic Number Time Limit: 2 Seconds      Memory Limit: 65536 KB A number that will be the same when it is written forwards or backwards is known as a palindromic number. For example, 1234321 is a palindromic number. We call a number 

zoj 3816 Generalized Palindromic Number (二分+贪心)

题目连接 : http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5348 牡丹江网络赛的题,比赛的时候想到做法的,但是一直没调出来,赛后也调了些时间,最近代码能力堪忧啊~ 有好多做法, 我的做法是二分下界low,即判断在low到n-1之间是否存在符合要求的数.然后贪心去构造一个解(直觉告诉我直接构造最大解好像很麻烦的样子). 构造解是这样的:首先low和n相同的前几位先放好,因为不管怎样这几位都是不变的,然后假如某一位不相同了,

ZOJ 3816 Generalized Palindromic Number dfs+暴力枚举

题目链接:点击打开链接 题意: 给定一个数n 找一个最大的数u使得u<n && u为回文. 枚举前面有多少位是一样的.然后分类讨论.啪啦啪啦 #include <cstdio> #include <algorithm> #include <cstring> #include <iostream> #include <vector> using namespace std; typedef long long ll; cons

[数位dp+二分] zoj Generalized Palindromic Number

题意: 找一个小于N的最大的且符合题意的数. 题意的数为,通过缩减后是回文的数,所谓的缩减就是相同连续的数看做一个数,如"155451111"其实就是"15451"是符合题意的数. 思路: 通过数位dp,然后二分求解. dp[i][j][k]代表第i位,已经放了j个数,最后长度是k的缩减回文数有几个. 然后需要一个ok[]数组代表放的数是什么,如果连续放相同的数就等于没放数. 遍历所有的长度就可以得到结果了. 其实不难发现,这种回文数一定是奇数位的. 代码: #in

Mudangjiang Online H Generalized Palindromic Number

一开始觉得是数位DP,后来想不出来. 但是感觉爆搜+剪枝可以过,于是就过了.. #include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long LL; const int maxn = 50; int lim[maxn], len; LL num; void getlim(LL n) { memset(lim, 0, sizeof(lim))

ZOJ3816-Generalized Palindromic Number(DFS数位搜索)

Generalized Palindromic Number Time Limit: 2 Seconds      Memory Limit: 65536 KB A number that will be the same when it is written forwards or backwards is known as a palindromic number. For example, 1234321 is a palindromic number. We call a number