SPOJ #692. Fruit Farm

Another palindrome related problem. Actually nothing too theoretical here, but please keep following hints in mind:

1. How to check whether a natural number is Palindrome
  Not sure whether there's closed form to Palindrome, I simply used a naive algorithm to check: log10() to get number of digits, and check mirrored digits.

2. Pre calculation
  1<=a<=b<=1000. so we can precalculate all Palindromes within that range beforehand.

3. Understand problem statement, only start from a Palindrome
  For each range, it must start from a Palindrome - we can simply skip non-Palindromes. And don't forget to remove all tailing non-Palindromes.

// 692 Fruit Farm
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;

/////////////////////////
#define gc getchar_unlocked
int read_int()
{
  char c = gc();
  while(c<'0' || c>'9') c = gc();
  int ret = 0;
  while(c>='0' && c<='9') {
    ret = 10 * ret + c - 48;
    c = gc();
  }
  return ret;
}
int read_string(char *p)
{
    int cnt = 0;
    char c;
    while((c = gc()) == ' ');    //    skip spaces
    //
    while(c != 10)
    {
        p[cnt ++] = c;
        c = gc();
    }
    return cnt;
}
void print_fast(const char *p, int len)
{
    fwrite(p, 1, len, stdout);
}
/////////////////////////
bool isPalin(int n)
{
    if(n >= 1 && n < 10) return true;

    //    Get digit length
    int nDigits = 1 + (int)floor(log10(n * 1.0));

    //    Get separated digits
    int digits[5] = {0};
    for(int i = 0; i < nDigits; i ++)
    {
        int d = n / (int)pow(10.0, i*1.0) % 10;
        digits[i] = d;
    }

    //    Check digits
    bool bEven = nDigits % 2 == 0;
    int inxLow = nDigits / 2 - 1;
    int inxHigh = (nDigits / 2) + (bEven ? 0 : 1);
    int nDigits2Check = nDigits / 2;
    for(int i = 0; i < nDigits2Check; i ++)
    {
        if(digits[inxLow] != digits[inxHigh]) return false;
        inxLow --; inxHigh ++;
    }
    return true;
}

bool Palin[1000] = {false};
void precalc_palin()
{
    for(int i = 1; i <= 1000; i ++)
    {
        if(isPalin(i))
        {
            Palin[i-1] = true;
            //printf("%d ", i);
        }
    }
    //printf("
");
}

void calc(int a, int b, int l)
{
    int rcnt = 0; int mya = 0, myb = 0;
    for(int i = a; i <= b; i++)
    {
        if(!Palin[i-1]) continue;
        //printf("At %d
", i);
        int cnt = 0; int bound = min(b, i + l - 1);
        for(int j = i; j <= bound; j ++)
        {
            if(Palin[j-1])    cnt ++;
        }
        //printf("[%d, %d] = %d	", i, bound, cnt);
        if(cnt > rcnt)
        {
            rcnt = cnt; mya = i; myb = bound;
        }
    }
    // shrink
    if(rcnt > 0)
    {
        while(!Palin[myb-1]) myb--;
        printf("%d %d
", mya, myb);
    }
    else
    {
        printf("Barren Land.
");
    }
}

int main()
{
    //    pre-calc all palindrome in [1-1000]
    precalc_palin();

    int runcnt = read_int();
    while(runcnt--)
    {
        int a = read_int();
        int b = read_int();
        int l = read_int();
        calc(a, b, l);
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/tonix/p/3555750.html