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 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

题意:找1~N-1中最大的数字(该数字压缩为回文串)

思路:采用数位DP的思想,枚举每一位,左右同时枚举,要从大到小枚举。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 20;
int lft[maxn],rgt[maxn];
vector<int> digit;
LL n,ans;
int len;
LL getS(int L,int R) {
	LL ret = 0;
	for(int i = 0; i < L; i++){
		ret *= 10;
		ret += lft[i];
	}
	for(int i = R; i >= 1; i--) {
		ret *= 10;
		ret += rgt[i];
	}
	return ret;
}
LL dfs(int L,int R,bool done) {
    if(L+R == len) {
        LL tmp = getS(L,R);
        if(tmp <= n-1) return tmp;
        else return 0;
    }
	int end = done?digit[L]:9;
	LL ans = 0;
	for(int i = end; i >= 0; i--) {
		lft[L] = i;
		if(L+R!=len-1&&(L==0||(L>=1&&lft[L]!=lft[L-1]))&&(L!=0||i!=0)){
            for(int k = 1; L+R+k <= len-1; k++) {
                rgt[k+R] = i;
                ans = max(dfs(L+1,R+k,done&&i==end),ans);
            }
		}else{
		    ans = max(dfs(L+1,R,done&&i==end),ans);
		}
		if(ans != 0) return ans;
	}
	return 0;
}
void init() {
	ans = 0;
	digit.clear();
	scanf("%lld",&n);
	LL x = n;
	--x;
	while(x) {
		digit.push_back(x%10);
		x /= 10;
	}
	len = digit.size();
	reverse(digit.begin(),digit.end());
}
void solve() {
    ans = dfs(0,0,true);
    printf("%lld\n",ans);
}
int main() {
	int ncase;
	cin >> ncase;
	while(ncase--) {
		init();
		solve();
	}
	return 0;
}
时间: 2024-08-10 13:42:11

ZOJ3816-Generalized Palindromic Number(DFS数位搜索)的相关文章

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 dfs+暴力枚举

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

[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

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

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

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

[数位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))

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

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