zoukankan      html  css  js  c++  java
  • CoFun 1616 数字游戏

    Description

    一个数x可以按以下规则生成数字:

    1、将任意两位交换,若交换的数字为a和b,生成的代价为((a and b)+(a xor b))*2 。   

    例如134可以生成431,因为431可以从134的个位(4)与百位(1)交换后得到,代价为((1 and 4)+(1 xor 4))*2=10。

    2、将其中一位数删除,但是删除的数要满足大等于它左边的数,且小等于它右边的数,并且定义最高位左边的数为个位,个位右边的数为最高位。若删除的数字为a,它左边的数为b,它右边的数为c,则生成的代价为a+(b and c)+(b xor c)。

      例如212,可以删除个位的数得到21,但是因为2>1,所以1是不能被删除的。特别地,若x为两位数,它能删除当且仅当x的两位数相同,若x为一位数,它是不能被删除的。

    3、在两位数字之间,也可以是数字的前面或后面加入一位数,同样地,加入的数要满足大等于它左边的数,且小等于它右边的数,并且定义最高位左边的数为个位,个位右边的数为最高位。若加入的数字为a,它左边的数为b,它右边的数为c,则生成的代价为a+(b and c)+(b xor c)。   

    例如241,它可以在2与4之间加入一个3,生成2341,也可以在数的末尾加入一个1或者2,当然还有其它可以生成的数,但是不能在4和1之间加入数字。

    你的任务是,S一开始为n个不同的给定数组成的集合,每次可以从S中取出一个数生成一个满足生成规则的数加入S中,并且取出的数仍然存在于S中。生成的数的位数不能大于S初始集合最大的数的位数。问在S元素最多的情况下,总代价最小是多少。

    Input Format

    输入的第1行为一个正整数n,为集合S初始元素个数。

    第2行包含n个正整数a1,a2, ..., an,数之间空格隔开,为S中初始元素。

    Output Format

    输出包括一个正整数,为最小代价。

    思路:如果a能生成b,那么b也可以生成a,首先我们从n个数里面bfs去生成其他数字,将代价建为边,由于要求最小的生成所有数的代价,因此很容易想到最小生成树,建一个0节点,对初始n个数字建边,边权为0,做最小生成树即可。

      1 #include<algorithm>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<iostream>
      6 #define ll long long
      7 struct edge{
      8     int u,v,w;
      9 }e[200005];
     10 int vis[1000005],c[1000005],b[1000005],n,tot,fa[200005],mx,h,t;
     11 bool cmp(edge a,edge b){
     12     return a.w<b.w;
     13 }
     14 int find(int x){
     15     if (fa[x]==x) return x;
     16     else return (fa[x]=find(fa[x]));
     17 }
     18 void MST(){
     19     for (int i=1;i<=n;i++){
     20         e[++tot].u=0;
     21         e[++tot].v=c[i];
     22         e[++tot].w=0;
     23     }
     24     std::sort(e+1,e+1+tot,cmp);
     25     for (int i=0;i<=100000;i++) fa[i]=i;
     26     ll ans=0;
     27     for (int i=1;i<=tot;i++){
     28         int p=find(e[i].u),q=find(e[i].v);
     29         if (p==q) continue;
     30         fa[p]=q;
     31         ans+=(ll)e[i].w;
     32     }
     33     printf("%lld
    ",ans);
     34 }
     35 int query(int x){
     36     int cnt=0;
     37     while (x){
     38         x/=10;cnt++;
     39     }
     40     return cnt;
     41 }
     42 void work(int x){
     43     int T=0,Len=0,y=x;
     44     while (y){
     45        b[Len++]=y%10;
     46        y/=10;
     47     }
     48     
     49     for (int i=0;i<Len;i++)
     50      for (int j=i+1;j<Len;j++){
     51             std::swap(b[i],b[j]);
     52             int cost=((b[i]&b[j])+(b[i]^b[j]))*2;
     53             T=0;
     54             for (int k=Len-1;k>=0;k--)
     55              T=T*10+b[k];
     56             if (T==x||query(T)>mx) continue; 
     57             if (!vis[T]) vis[T]=1,c[++t]=T; 
     58             e[++tot].u=x;e[tot].v=T;e[tot].w=cost;
     59             std::swap(b[i],b[j]);
     60     }
     61     if (Len>2){
     62      for (int i=0;i<Len;i++){
     63         int L=b[(i+1)%Len],R=b[(i-1+Len)%Len];
     64         if (b[i]<L||b[i]>R) continue;
     65         int cost=b[i]+(L^R)+(L&R);
     66         T=0;
     67         for (int j=Len-1;j>=0;j--)
     68          if (j!=i)
     69           T=T*10+b[j];
     70         if (query(T)>mx) continue;  
     71         e[++tot].u=x,e[tot].v=T,e[tot].w=cost;
     72         if (!vis[T]) vis[T]=1,c[++t]=T;  
     73      }
     74     }else
     75     if (Len==2){
     76         if (b[0]==b[1]){
     77             T=b[0];
     78             if (query(T)<=mx){
     79                if (!vis[T]) vis[T]=1,c[++t]=T;
     80                int cost=b[0]+(b[0]^b[1])+(b[0]&b[1]);
     81                e[++tot].u=x;e[tot].v=T;e[tot].w=cost;
     82             }
     83         }
     84     }
     85     for (int i=0;i<Len;i++){
     86         int L=b[(i+1)%Len],R=b[(i+Len)%Len];
     87         for (int j=L;j<=R;j++){
     88             T=0;
     89             for (int k=Len-1;k>=0;k--)
     90              if (k==i)
     91               T=T*10+j,T=T*10+b[k];
     92              else 
     93               T=T*10+b[k];
     94             if (query(T)>mx) break;
     95             if (!vis[T]) vis[T]=1,c[++t]=T;
     96             int cost=T+(L^R)+(L&R);
     97             e[++tot].u=x;e[tot].v=T;e[tot].w=cost; 
     98         }
     99     }
    100     int L=b[0],R=b[Len-1];
    101     for (int j=L;j<=R;j++){
    102         T=0;
    103         for (int k=Len-1;k>=0;k--)
    104          T=T*10+b[k];
    105         T=T*10+j;
    106         if (query(T)>mx) break;
    107         if (!vis[T]) vis[T]=1,c[++t]=T;
    108         int cost=T+(L^R)+(L&R);
    109         e[++tot].u=x;e[tot].v=T;e[tot].w=cost; 
    110     }
    111 }
    112 int main(){
    113     scanf("%d",&n);
    114     for (int i=1;i<=n;i++){
    115         scanf("%d",&c[i]);
    116         int T=c[i],cnt=0;
    117         while (T){
    118             cnt++;T/=10;
    119         }
    120         mx=std::max(mx,cnt);
    121         vis[c[i]]=1;
    122     }
    123     h=1,t=n;
    124     while (h<=t){
    125         int now=c[h++];
    126         work(now);
    127     }
    128     for (int i=1;i<=t;i++)
    129      printf("%d
    ",c[i]);
    130     MST();
    131 }
  • 相关阅读:
    如何用CSS实现中间自适应,两边定宽三栏布局
    [转]通过Spring Boot三分钟创建Spring Web项目
    [转]Java Web笔记:搭建环境和项目配置(MyEclipse 2014 + Maven + Tomcat)
    [转]单元测试、集成测试、确认测试、系统测试、验收测试
    [转]maven全局配置文件settings.xml详解
    [转]解决-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME environment variable and mvn script match.
    [转]PO BO VO DTO POJO DAO概念及其作用(附转换图)
    [转]如何提升你的能力?给年轻程序员的几条建议
    从oracle导出数据成csv,将csv导入mongodb问题
    Windows下Mongodb启动问题
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5553808.html
Copyright © 2011-2022 走看看