• [zoj3596]DP(BFS)


    题意:求n的最小倍数,满足性质P:十进制的每一位上的数有m种(0<m<=10)。

    思路:直接枚举n的最小倍数,然后检测是否满足性质P,n一大很容易超时,并且无法判断无解的情况。巧妙的做法是一位位构造数,同时保存每种数字的使用情况和对n的余数作为状态,如果一个状态出现过,那么后面再一次出现的时候位数肯定比之前多,故答案没之前优,舍弃。由于取模的性质,转移方程也很好写,具体见代码。

      1 #pragma comment(linker, "/STACK:10240000,10240000")
      2 
      3 #include <iostream>
      4 #include <cstdio>
      5 #include <algorithm>
      6 #include <cstdlib>
      7 #include <cstring>
      8 #include <map>
      9 #include <queue>
     10 #include <deque>
     11 #include <cmath>
     12 #include <vector>
     13 #include <ctime>
     14 #include <cctype>
     15 #include <set>
     16 #include <bitset>
     17 #include <functional>
     18 #include <numeric>
     19 #include <stdexcept>
     20 #include <utility>
     21 
     22 using namespace std;
     23 
     24 #define mem0(a) memset(a, 0, sizeof(a))
     25 #define mem_1(a) memset(a, -1, sizeof(a))
     26 #define lson l, m, rt << 1
     27 #define rson m + 1, r, rt << 1 | 1
     28 #define define_m int m = (l + r) >> 1
     29 #define rep_up0(a, b) for (int a = 0; a < (b); a++)
     30 #define rep_up1(a, b) for (int a = 1; a <= (b); a++)
     31 #define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
     32 #define rep_down1(a, b) for (int a = b; a > 0; a--)
     33 #define all(a) (a).begin(), (a).end()
     34 #define lowbit(x) ((x) & (-(x)))
     35 #define constructInt5(name, a, b, c, d, e) name(int a = 0, int b = 0, int c = 0, int d = 0, int e = 0): a(a), b(b), c(c), d(d), e(e) {}
     36 #define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
     37 #define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
     38 #define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
     39 #define pchr(a) putchar(a)
     40 #define pstr(a) printf("%s", a)
     41 #define sstr(a) scanf("%s", a)
     42 #define sint(a) scanf("%d", &a)
     43 #define sint2(a, b) scanf("%d%d", &a, &b)
     44 #define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
     45 #define pint(a) printf("%d
    ", a)
     46 #define test_print1(a) cout << "var1 = " << a << endl
     47 #define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
     48 #define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
     49 #define mp(a, b) make_pair(a, b)
     50 #define pb(a) push_back(a)
     51 
     52 typedef long long LL;
     53 typedef pair<int, int> pii;
     54 typedef vector<int> vi;
     55 
     56 const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
     57 const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
     58 const int maxn = 3e4 + 7;
     59 const int md = 10007;
     60 const int inf = 1e9 + 7;
     61 const LL inf_L = 1e18 + 7;
     62 const double pi = acos(-1.0);
     63 const double eps = 1e-6;
     64 
     65 template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
     66 template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
     67 template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
     68 template<class T>T condition(bool f, T a, T b){return f?a:b;}
     69 template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
     70 int make_id(int x, int y, int n) { return x * n + y; }
     71 
     72 const int maxI = 1e8;
     73 const int Len = 8;
     74 
     75 struct BigInt {
     76     vi num;
     77     bool symbol;
     78     BigInt() { num.clear(); symbol = 0; }
     79     BigInt(int x) { symbol = 0; if (x < 0) { symbol = 1; x = -x; } num.push_back(x % maxI); if (x >= maxI) num.push_back(x / maxI); }
     80     BigInt(bool s, vi x) { symbol = s;  num = x; }
     81     BigInt(char s[]) {
     82         int len = strlen(s), x = 1, sum = 0, p = s[0] == '-';
     83         symbol = p;
     84         for (int i = len - 1; i >= p; i--) {
     85             sum += (s[i] - '0') * x;
     86             x *= 10;
     87             if (x == 1e8 || i == p) {
     88                 num.push_back(sum);
     89                 sum = 0;
     90                 x = 1;
     91             }
     92         }
     93         while (num.back() == 0 && num.size() > 1) num.pop_back();
     94     }
     95 
     96     void push(int x) { num.push_back(x); }
     97 
     98     BigInt abs() const { return BigInt(false, num); }
     99 
    100     bool smaller(const vi &a, const vi &b) const {
    101         if (a.size() != b.size()) return a.size() < b.size();
    102         for (int i = a.size() - 1; i >= 0; i--) {
    103             if (a[i] != b[i]) return a[i] < b[i];
    104         }
    105         return 0;
    106     }
    107 
    108     bool operator < (const BigInt &p) const {
    109         if (symbol && !p.symbol) return true;
    110         if (!symbol && p.symbol) return false;
    111         if (symbol && p.symbol) return smaller(p.num, num);
    112         return smaller(num, p.num);
    113     }
    114 
    115     bool operator > (const BigInt &p) const {
    116         return p < *this;
    117     }
    118 
    119     bool operator == (const BigInt &p) const {
    120         return !(p < *this) && !(*this < p);
    121     }
    122 
    123     bool operator >= (const BigInt &p) const {
    124         return !(*this < p);
    125     }
    126 
    127     bool operator <= (const BigInt &p) const {
    128         return !(p < *this);
    129     }
    130 
    131     vi add(const vi &a, const vi &b) const {
    132         vi c;
    133         c.clear();
    134         int x = 0;
    135         for (int i = 0; i < a.size(); i++) {
    136             x += a[i];
    137             if (i < b.size()) x += b[i];
    138             c.push_back(x % maxI);
    139             x /= maxI;
    140         }
    141         for (int i = a.size(); i < b.size(); i++) {
    142             x += b[i];
    143             c.push_back(x % maxI);
    144             x /= maxI;
    145         }
    146         if (x) c.push_back(x);
    147         while (c.back() == 0 && c.size() > 1) c.pop_back();
    148         return c;
    149     }
    150 
    151     vi sub(const vi &a, const vi &b) const {
    152         vi c;
    153         c.clear();
    154         int x = 1;
    155         for (int i = 0; i < b.size(); i++) {
    156             x += maxI + a[i] - b[i] - 1;
    157             c.push_back(x % maxI);
    158             x /= maxI;
    159         }
    160         for (int i = b.size(); i < a.size(); i++) {
    161             x += maxI + a[i] - 1;
    162             c.push_back(x % maxI);
    163             x /= maxI;
    164         }
    165         while (c.back() == 0 && c.size() > 1) c.pop_back();
    166         return c;
    167     }
    168 
    169     vi mul(const vi &a, const vi &b) const {
    170         vi c;
    171         c.resize(a.size() + b.size());
    172         for (int i = 0; i < a.size(); i++) {
    173             for (int j = 0; j < b.size(); j++) {
    174                 LL tmp = (LL)a[i] * b[j] + c[i + j];
    175                 c[i + j + 1] += tmp / maxI;
    176                 c[i + j] = tmp % maxI;
    177             }
    178         }
    179         while (c.back() == 0 && c.size() > 1) c.pop_back();
    180         return c;
    181     }
    182 
    183     vi div(const vi &a, const vi &b) const {
    184         vi c(a.size()), x(1, 0), y(1, 0), z(1, 0), t(1, 0);
    185         y.push_back(1);
    186         for (int i = a.size() - 1; i >= 0; i--) {
    187             z[0] = a[i];
    188             x = add(mul(x, y), z);
    189             if (smaller(x, b)) continue;
    190             int l = 1, r = maxI - 1;
    191             while (l < r) {
    192                 int m = (l + r + 1) >> 1;
    193                 t[0] = m;
    194                 if (smaller(x, mul(b, t))) r = m - 1;
    195                 else l = m;
    196             }
    197             c[i] = l;
    198             t[0] = l;
    199             x = sub(x, mul(b, t));
    200         }
    201         while (c.back() == 0 && c.size() > 1) c.pop_back();
    202         return c;
    203     }
    204 
    205     BigInt operator + (const BigInt &p) const{
    206         if (!symbol && !p.symbol) return BigInt(false, add(num, p.num));
    207         if (!symbol && p.symbol) return *this >= p.abs()? BigInt(false, sub(num, p.num)) : BigInt(true, sub(p.num, num));
    208         if (symbol && !p.symbol) return (*this).abs() > p? BigInt(true, sub(num, p.num)) : BigInt(false, sub(p.num, num));
    209         return BigInt(true, add(num, p.num));
    210     }
    211 
    212     BigInt operator - (const BigInt &p) const {
    213         return *this + BigInt(!p.symbol, p.num);
    214     }
    215 
    216     BigInt operator * (const BigInt &p) const {
    217         BigInt res(symbol ^ p.symbol, mul(num, p.num));
    218         if (res.symbol && res.num.size() == 1 && res.num[0] == 0) res.symbol = false;
    219         return res;
    220     }
    221 
    222     BigInt operator / (const BigInt &p) const {
    223         if (p == BigInt(0)) return p;
    224         BigInt res(symbol ^ p.symbol, div(num, p.num));
    225         if (res.symbol && res.num.size() == 1 && res.num[0] == 0) res.symbol = false;
    226         return res;
    227     }
    228 
    229     BigInt operator % (const BigInt &p) const {
    230         return *this - *this / p * p;
    231     }
    232 
    233     void show() const {
    234         if (symbol) putchar('-');
    235         printf("%d", num[num.size() - 1]);
    236         for (int i = num.size() - 2; i >= 0; i--) {
    237             printf("%08d", num[i]);
    238         }
    239         //putchar('
    ');
    240     }
    241 
    242     int TotalDigit() const {
    243         int x = num[num.size() - 1] / 10, t = 1;
    244         while (x) {
    245             x /= 10;
    246             t++;
    247         }
    248         return t + (num.size() - 1) * Len;
    249     }
    250 
    251 };
    252 typedef BigInt bi;
    253 
    254 struct Node {
    255     int used, rest, cnt, fa, val;
    256     constructInt5(Node, used, rest, cnt, fa, val);
    257 } que[3000000];
    258 bool mark[1 << 10][1000];
    259 int n, m;
    260 
    261 bi get(int pos) {
    262     if (pos == 0) return 0;
    263     return get(que[pos].fa) * 10 + que[pos].val;
    264 }
    265 
    266 void bfs() {
    267     mem0(mark);
    268     int head = 0, tail = 0;
    269     que[tail ++] = Node(0, 0, 0, 0, 0);
    270     Node hnode;
    271     while (head < tail) {
    272         hnode = que[head ++];
    273         if (hnode.cnt > m) continue;
    274         if (hnode.cnt == m && hnode.rest == 0) break;
    275         rep_up0(i, 10) {
    276             if (hnode.cnt == 0 && i == 0) continue;
    277             if (hnode.used & (1 << i)) {
    278                 Node newn = Node(hnode.used, (hnode.rest * 10 + i) % n, hnode.cnt, head - 1, i);
    279                 if (mark[newn.used][newn.rest]) continue;
    280                 mark[newn.used][newn.rest] = true;
    281                 que[tail ++] = newn;
    282             }
    283             else {
    284                 Node newn = Node(hnode.used | (1 << i), (hnode.rest * 10 + i) % n, hnode.cnt + 1, head - 1, i);
    285                 if (mark[newn.used][newn.rest]) continue;
    286                 mark[newn.used][newn.rest] = true;
    287                 que[tail ++] = newn;
    288             }
    289         }
    290     }
    291     if (hnode.cnt != m || hnode.rest != 0) {
    292         puts("Impossible");
    293         return ;
    294     }
    295     bi ans = get(head - 1);
    296     ans.show();
    297     printf("=%d*", n);
    298     (ans / n).show();
    299     pchr('
    ');
    300 }
    301 
    302 int main() {
    303     //freopen("in.txt", "r", stdin);
    304     int T;
    305     cin >> T;
    306     while (T --) {
    307         cin >> n >> m;
    308         bfs();
    309     }
    310     return 0;
    311 }
    View Code
  • 相关阅读:
    【C++】资源管理
    【Shell脚本】逐行处理文本文件
    【算法题】rand5()产生rand7()
    【Shell脚本】字符串处理
    Apple iOS产品硬件参数. 不及格的程序员
    与iPhone的差距! 不及格的程序员
    iPhone游戏 Mr.Karoshi"过劳死"通关. 不及格的程序员
    XCode V4 发布了, 苹果的却是个变态. 不及格的程序员
    何时readonly 字段不是 readonly 的?结果出呼你想象!!! 不及格的程序员
    object file format unrecognized, invalid, or unsuitable Command 不及格的程序员
  • 原文地址:https://www.cnblogs.com/jklongint/p/4480793.html
Copyright © 2020-2023  润新知