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


    题目连接 : http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5348

    牡丹江网络赛的题,比赛的时候想到做法的,但是一直没调出来,赛后也调了些时间,最近代码能力堪忧啊~

    有好多做法, 我的做法是二分下界low,即判断在low到n-1之间是否存在符合要求的数。然后贪心去构造一个解(直觉告诉我直接构造最大解好像很麻烦的样子)。

    构造解是这样的:首先low和n相同的前几位先放好,因为不管怎样这几位都是不变的,然后假如某一位不相同了,那么后面的位置上放数就不需要考虑下界了,直接贪心出最小解就行了,比较最小解与N的大小就行了,也就是最后问题变成了前几位确定的,总的位数也是确定的,求最小解,这个可以贪心搞的,不过需要枚举中间在哪里,注意可以在中间放0喔。具体细节看代码。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <iostream>
      5 #include <time.h>
      6 
      7 using namespace std;
      8 typedef long long lld;
      9 const int MAXN = 55;
     10 const lld INF = 1LL<<62;
     11 int bit[MAXN];
     12 int BIT[MAXN];
     13 lld n;
     14 int m;
     15 int arr[MAXN];
     16 
     17 lld calc(int a[], int cnt, int mid, int inx) {
     18     if (2 * mid - cnt > inx) return INF;
     19     lld ret = 0;
     20     for (int i = m; i >= inx; i--) {
     21         ret *= 10; ret += arr[i];
     22     }
     23     for (int i = mid + 1; i <= cnt; i++) {
     24         if (2 * mid - i <= 0 || a[i] != a[2 * mid - i]) return INF;
     25     }
     26     int ind = 2 * mid - cnt;
     27     for (int i = inx - 1; i >= 1 && ind >= 1; i--) {
     28         ret *= 10;
     29         if (ind == 1) {
     30             ret += a[ind];
     31         }else {
     32             if (ind-1 == i || a[ind-1] <= a[ind]) {
     33                 ret += a[ind-1]; ind--;
     34             }else {
     35                 ret += a[ind];
     36             }
     37         }
     38     }
     39     return ret;
     40 }
     41 
     42 int isok(int inx) {
     43     int cnt = 0;
     44     int a[MAXN];
     45     for (int i = m; i >= inx; i--) {
     46         if (arr[i] != 0) {
     47             a[++ cnt] = arr[i];
     48             for (int j = i - 1; j >= inx; j--) {
     49                 if (a[cnt] != arr[j]) a[++ cnt] = arr[j];
     50             }
     51             break;
     52         }
     53     }
     54     for (int i = cnt/2; i <= cnt; i++) {
     55         lld ret = calc(a, cnt, i, inx);
     56         if (ret <= n) return 1;
     57     }
     58     a[++ cnt] = 0;
     59     return calc(a, cnt, cnt, inx) <= n;
     60 }
     61 
     62 int solve() {
     63     for (int i = m, fg = 0; i >= 1; i--) {
     64         if (bit[i] == BIT[i] && !fg) {
     65             arr[i] = bit[i]; continue;
     66         }
     67         int Max = (fg >= 1 ? 9 : BIT[i]);
     68         for (int j = Max; j >= bit[i] + 1; j--) {
     69             arr[i] = j;
     70             if (isok(i)) return 1;
     71         }
     72         arr[i] = bit[i];
     73         fg ++;
     74     }
     75     int a[MAXN], cnt = 1;
     76     a[1] = arr[m];
     77     for (int i = m - 1; i >= 1; i--) {
     78         if (a[cnt] != arr[i]) a[++ cnt] = arr[i];
     79     }
     80     for (int i = 1; i <= cnt/2; i++) {
     81         if (a[i] != a[cnt-i+1]) return 0;
     82     }
     83     return 1;
     84 }
     85 
     86 int check(lld x) {
     87     int len = 0;
     88     memset(bit, 0, sizeof(bit));
     89     memset(arr, 0, sizeof(arr));
     90     while (x) {
     91         bit[++ len] = x % 10;
     92         x /= 10;
     93     }
     94     return solve();
     95 }
     96 int main() {
     97     int T;
     98     scanf("%d", &T);
     99     for (int cas = 1; cas <= T; cas++) {
    100         cin >> n;
    101         int ret;
    102         if (n == 1) {
    103             printf("0
    "); continue;
    104         }
    105         n = n - 1;
    106         lld l = 1, r = n;
    107         m = 0;
    108         lld tmp = n;
    109         while (tmp) {
    110             BIT[++ m] = tmp % 10;
    111             tmp /= 10;
    112         }
    113         while (r >= l) {
    114             lld mid = r + l >> 1;
    115             if (check(mid)) {
    116                 l = mid + 1;
    117             }else {
    118                 r = mid - 1;
    119             }
    120         }
    121         cout << l - 1 << endl;
    122     }
    123     return 0;
    124 }
    View Code
  • 相关阅读:
    【Qt开发】QTableWidget设置根据内容调整列宽和行高
    【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
    【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
    【Qt开发】Qt5.7串口开发
    【Qt开发】Qt5.7串口开发
    Oracle监听配置、数据库实例配置等
    SqlMapConfig.xml中的setting属性 Ibatis mybatis
    Hibernate的like用法
    eclipse逆向生成实体类注解方式或者xml方式
    struts2 ValueStack详解,页面获取值el表达式、ognl表达式
  • 原文地址:https://www.cnblogs.com/danceonly/p/3960771.html
Copyright © 2020-2023  润新知