1. 程式人生 > >Hdu 6156 Palindrome Function

Hdu 6156 Palindrome Function

Palindrome Function

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Others)
Total Submission(s): 193    Accepted Submission(s): 103


Problem Description As we all know,a palindrome number is the number which reads the same backward as forward,such as 666 or 747.Some numbers are not the palindrome numbers in decimal form,but in other base,they may become the palindrome number.Like 288,it’s not a palindrome number under 10-base.But if we convert it to 17-base number,it’s GG,which becomes a palindrome number.So we define an interesting function f(n,k) as follow:
f(n,k)=k if n is a palindrome number under k-base.
Otherwise f(n,k)=1.
Now given you 4 integers L,R,l,r,you need to caluclate the mathematics expression 
Ri=L
rj=lf(i,j)
 .
When representing the k-base(k>10) number,we need to use A to represent 10,B to represent 11,C to repesent 12 and so on.The biggest number is Z(35),so we only discuss about the situation at most 36-base number.
Input The first line consists of an integer T,which denotes the number of test cases.
In the following T lines,each line consists of 4 integers L,R,l,r.
(1
T105,1LR109,2lr36
)
Output For each test case, output the answer in the form of “Case #i: ans” in a seperate line.
Sample Input 3 1 1 2 36 1 982180 10 10 496690841 524639270 5 20
Sample Output Case #1: 665 Case #2: 1000000 Case #3: 447525746
Source

亂搞題。

只要求各進位制下回文數個數就好了,答案就是R以內的迴文數個數減去L以內的迴文數個數。

設個數為cnt,答案就是cnt*(k-1)+n

證明:

f(n,k)=k if n is a palindrome number under k-base.
Otherwise f(n,k)=1.
先加n,相當於把所有的函式值都當做1。
剩下cnt個迴文數每個f(n,k)的值都為k,總的貢獻是cnt*k,但是之前已經算了1,所以再加cnt*(k-1)

那麼只需要列舉迴文數。

設迴文半徑為n,則整個數長度為2*n-1或2*n.只要列舉迴文數前一半。

前一半比當前數前一半小的且總長度不超過當前數的,必然可以構造成功。

那麼只要特判一下前一半和當前數相等的情況就好了。

655ms AC

比賽時候過早搞出來了這題,導致後半程都在掛機。。。

#include <cstdio>
#include <iostream>
#include <string.h>
#include <string> 
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int maxn=100005,inf=0x3f3f3f3f;  
const ll llinf=0x3f3f3f3f3f3f3f3f;   
const ld pi=acos(-1.0L);  
ll num[105];

ll convert(ll n,ll k) {
	if (n==0) return 0;
	ll i=n,len=0,cnt=0,l;
	while (i) {
		num[len++]=i%k;
		i/=k;
	}
	ll p=0,sum=1,base=k;
	for (i=1;i<len;i++) {
		cnt+=base-sum;
		if (i%2==0) {
			sum=base;
			base*=k;
		}
	}
	for (i=len-1;i>=len/2;i--) {
		p=p*k+num[i];
	}
	l=p;
	ll o;
	if (len%2) o=len/2+1; else o=len/2;
	for (i=o;i<len;i++) {
		p=p*k+num[i];
	}
	if (p>n) cnt+=l-sum; else cnt+=l-sum+1;
	return cnt*(k-1)+n;
}

int main() {
	int cas,q=0;
	scanf("%d",&cas);
	while (cas--) {
		ll l,r,k,p,i,j;
		q++;
		ll sum=0;
		scanf("%lld%lld%lld%lld",&l,&r,&k,&p);
		for (i=k;i<=p;i++) {
			sum+=convert(r,i);
			sum-=convert(l-1,i);
		}
		printf("Case #%d: %lld\n",q,sum);
	}
	return 0;
}