zoukankan      html  css  js  c++  java
  • hdu1664 bfs+余数判重

    input

    n    不超过50个例子,n==0结束输入

    Sample Input

    7 15 16 101 0

    output

    最少个不同数字的n的倍数的x,若不同数字个数一样,输出最小的x

    Sample Output

    7 555 16 1111

    根据数论里面的知识点:

    对于任意的整数 n ,必然存在一个由不多于两个的数来组成的一个倍数。 因为 a ,aa , aaa…… 取 n+1 个,则由鸽笼原理,必有两个模 n 余数相同,相减即得 n 的倍数 m 。而 m 只由 a 、 0 组成。

      1 #include <bits/stdc++.h>
      2 #include <cstdio>
      3 #include <queue>
      4 #include <cstring>
      5 #include <iostream>
      6 #include <cstdlib>
      7 #include <algorithm>
      8 #include <vector>
      9 #include <map>
     10 #include <set>
     11 #include <ctime>
     12 #include <cmath>
     13 #include <cctype>
     14 #include <string>
     15 #include <bitset>
     16 #define MAX 65600
     17 #define LL long long
     18 #define uint unsigned short
     19 using namespace std;
     20 int cas=1,T,n;
     21 struct node1
     22 {
     23     int i,r;
     24 };
     25 char v1[MAX][10];
     26 int bfs1()
     27 {
     28     int step=1,d=0;
     29     queue<node1>q[2];
     30     memset(v1,0,sizeof(v1[0])*n);
     31     for(int i=1;i<10;i++) { q[0].push((node1){i,i%n});v1[i%n][i]=1; }
     32     while(!q[d].empty())            //两个队列bfs,一个队列存一步里面走的
     33     {
     34         while(!q[d].empty())
     35         {
     36             node1 u=q[d].front();q[d].pop();
     37             if(u.r==0)
     38             {
     39                 for(int i=0;i<step;i++) printf("%d",u.i);
     40                 printf("
    ");
     41                 return 1;
     42             }
     43             node1 v;
     44             v.r=(u.r*10+u.i)%n;
     45             if(v1[v.r][u.i]) continue;
     46             v.i=u.i;q[d^1].push(v);
     47             v1[v.r][u.i]=1;
     48         }
     49         step++;
     50         d^=1;
     51     }
     52     return 0;
     53 }
     54 struct node
     55 {
     56     uint r,i,a,b;        //a,b是两个不同的数字且a<b<10,r是余数,i是当前取的数,输出时要用
     57     int fa;                //父结点,查找路径用
     58 };
     59 node q[MAX*45];
     60 char v[MAX][45];
     61 uint idx(uint &a,uint&b) { return (b*b-b)/2+a; }
     62 void init(int &end)            //初始化队列,一次将所有的入队用的内存太多,也可以分成45次bfs()
     63 {
     64     for(int i=10;i<100;i++)        //从小到大入队
     65     {
     66         int a=i/10,b=i%10;                //a是个位,b是十位
     67         if(a==b)//a,b相同时可以是550 551 552 553 554 556 557 558 559
     68         {
     69             for(int j=0;j<10;j++)
     70             {
     71                 if(a==j) continue;
     72                 node&u=q[end];
     73                 u.i=i;u.r=i%n;
     74                 u.a=min(a,j);u.b=max(a,j);u.fa=-1;
     75                 int id=idx(u.a,u.b);
     76                 v[a][id]=v[i][id]=1;
     77                 end++;
     78 //                printf("%d %d %d %d %d
    ",u.i,u.r,u.a,u.b,u.fa);
     79             }
     80             continue;
     81         }
     82         node&u=q[end];        //a,b不同时直接入队即可
     83         u.i=i;u.r=i%n;
     84         u.a=min(a,b);u.b=max(a,b);u.fa=-1;
     85         int id=idx(u.a,u.b);
     86         v[a][id]=v[i][id]=1;
     87         end++;
     88 //        printf("%d %d %d %d %d
    ",u.i,u.r,u.a,u.b,u.fa);
     89     }
     90 }
     91 void print(int u)
     92 {
     93     if(q[u].fa==-1) { printf("%d",q[u].i);return; }
     94     print(q[u].fa);
     95     printf("%d",q[u].i);
     96 }
     97 void bfs2()    
     98 {
     99     memset(v,0,sizeof(v[0])*n);
    100     int front=0,end=0;
    101     init(end);
    102     while(front<end)
    103     {
    104         node&u=q[end],&f=q[front];
    105         int id=idx(f.a,f.b);
    106         if(f.r==0) { print(front);printf("
    ");return; }
    107         u.r=((int)f.r*10+f.a)%n;
    108         if(!v[u.r][id])        //加一位a
    109         {
    110             v[u.r][id]=1;                //刚开始错在这,没有标记,也是够傻了。。。而且还一直找不到。。。
    111             u.a=f.a;u.b=f.b;u.fa=front;
    112             u.i=f.a;
    113             end++;
    114         }
    115         node&p=q[end];
    116         p.r=((int)f.r*10+f.b)%n;
    117         if(!v[p.r][id])        //加一位b
    118         {
    119             v[p.r][id]==1;
    120             p.a=f.a;p.b=f.b;p.fa=front;
    121             p.i=f.b;
    122             end++;
    123         }
    124         front++;
    125 //        printf("%d %d
    ",front,end);
    126     }
    127 }
    128 int main()
    129 {
    130     //freopen("out","w",stdout);
    131     //freopen("in","r",stdin);
    132     //scanf("%d",&T);
    133     while(scanf("%d",&n)==1&&n)
    134     //for(n=65535;n>0;n--)
    135     {
    136         if(bfs1()) continue;
    137         bfs2();
    138     }
    139     //printf("time=%.3lf
    ",(double)clock()/CLOCKS_PER_SEC);
    140     return 0;
    141 }
    View Code
  • 相关阅读:
    冬季小学期 NIIT公司 web前端培训 javascript
    冬季小学期 NIIT公司 web前端培训 CSS
    冬季小学期 NIIT公司 web前端培训 HTML
    操作系统 思维导图 百度脑图
    验证码识别系统以及人工智能总结 神经网络encog图像识别入门
    eclipse 常用操作 持续更新
    大话设计模式笔记 访客模式
    [百度杯-二月场](Misc-Web)爆破-2
    [百度杯-二月场](Misc-Web)爆破-1
    jdk1.7中的常量池
  • 原文地址:https://www.cnblogs.com/cdyboke/p/5066798.html
Copyright © 2011-2022 走看看