首页 > 代码库 > bzoj1111 [POI2007]四进制的天平Wag

bzoj1111 [POI2007]四进制的天平Wag

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1111

【题解】

这题号注定单身。

转成四进制考虑

设f[i]表示从第i位往前的min,g[i]表示从第i位往前(第i位借1位)往前的min

那么转移随便做了。。

md还要取模,没看这个wa了3发

技术分享
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 8e3 + 10;
const int mod = 1e9;

# define RG register
# define ST static

int a[M], b[M]; 
int n[M], N = 0;
char str[M];
struct pa {
    int x, num;
    pa() {}
    pa(int x, int num) : x(x), num(num) {}
}f[M], g[M];

inline pa cmin(pa a, pa b, int c) {
    b.x += c;
    if(b.x < a.x) a = b;
    else if(b.x == a.x) (a.num += b.num) %= mod;
    return a;
}

inline int div(int *a) {
    b[0] = 0; 
    int x = 0;
    for (int i=1; i<=a[0]; ++i) {
        b[++b[0]] = (x*10 + a[i])/4;
        x = (x*10 + a[i])%4; 
    }
    int len = 0; 
    while(b[len+1] == 0 && len < a[0]) ++len; 
//    printf("%d\n", b[0]); system("pause");
    a[0] = 0; 
    for (int i=len+1; i<=b[0]; ++i) a[++a[0]] = b[i];
//    cout << endl;
//    cout << "mod res = " << x << endl; 
    return x;
}         

inline void transform() {
    while(a[0] != 0) 
        n[++N] = div(a);
}

int main() {
    scanf("%s", str);
    int x = 0;
    a[0] = 0; 
    for (int i=0; str[i]; ++i) {
        ++a[0];
        a[a[0]] = str[i] - 0;
    }
    
    transform(); 
    
//    cout << N << endl;
//    for (int i=1; i<=N; ++i) cout << n[i];
//    cout << endl; 
    
    for (int i=N+1; i; --i) f[i] = pa(1e9, 0), g[i] = pa(1e9, 0);
    // 从第i位往前,从第i位(这一位借位了)往前 
    f[N+1] = pa(0, 1), g[N+1] = pa(1, 1);
    for (int i=N; i; --i) {
        if(n[i] == 0) {
            f[i] = cmin(f[i], f[i+1], 0);
            f[i] = cmin(f[i], g[i+1], 4); 
            g[i] = cmin(g[i], f[i+1], 1);
            g[i] = cmin(g[i], g[i+1], 3); 
        } else if(n[i] == 1) {
            f[i] = cmin(f[i], f[i+1], 1);
            f[i] = cmin(f[i], g[i+1], 3);
            g[i] = cmin(g[i], f[i+1], 2);
            g[i] = cmin(g[i], g[i+1], 2); 
        } else if(n[i] == 2) {
            f[i] = cmin(f[i], f[i+1], 2);
            f[i] = cmin(f[i], g[i+1], 2);
            g[i] = cmin(g[i], f[i+1], 3);
            g[i] = cmin(g[i], g[i+1], 1); 
        } else {
            f[i] = cmin(f[i], f[i+1], 3);
            f[i] = cmin(f[i], g[i+1], 1);
            g[i] = cmin(g[i], f[i+1], 4);
            g[i] = cmin(g[i], g[i+1], 0); 
        }
    }
    
    cout << f[1].num << endl; 
    
    return 0;
}
View Code

 

bzoj1111 [POI2007]四进制的天平Wag