zoukankan      html  css  js  c++  java
  • [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
  • 相关阅读:
    Non-Photorealistic Rendering using OpenCV ( Python, C++ )
    Tensorflow Eager execution and interface
    Linear and Logistic Regression in TensorFlow
    TensorFlow Ops
    Introduction to TensorFlow
    Java Syntax Specification
    java方法的虚分派和方法表
    λ演算
    活性变量分析
    java垃圾回收机制
  • 原文地址:https://www.cnblogs.com/jklongint/p/4480793.html
Copyright © 2011-2022 走看看