zoukankan      html  css  js  c++  java
  • A

    题目链接:https://vjudge.net/contest/276374#problem/A

    题目大意:给你20个杯子,每一次操作,假设当前是对第i个位置进行操作,那么第i个位置,第i+1个位置,第i-1个位置的盘子都会翻转,第一个和最后一个例外(只有两个)。然后问你最少的操作数能够使得盘子全部变成反着的(0代表反,1代表正)。

    bfs的做法:

    具体思路:bfs,注意起点为0个操作的情况,然后逐步的去找满足题目条件的最优步数。如果是起点是初始状态,然后去找全部都是翻转的情况,这样的话会mle,因为递归层数会明显的比第一种的多。

    AC代码:

     1 #include<iostream>
     2 #include<stack>
     3 #include<cstring>
     4 #include<iomanip>
     5 #include<stdio.h>
     6 #include<algorithm>
     7 #include<cmath>
     8 #include<queue>
     9 using namespace std;
    10 # define ll long long
    11 # define inf 1ll<<60
    12 const int mod = 21252;
    13 const int maxn = 1<<23;
    14 struct node
    15 {
    16     int num;
    17     int step;
    18     node() {}
    19     node(int xx,int yy)
    20     {
    21         num=xx,step=yy;
    22     }
    23 }q[maxn];
    24 int vis[maxn];
    25 bool check(int t)
    26 {
    27     for(int i=0; i<20; i++)
    28     {
    29         if((1<<i)&t)
    30             return false;
    31     }
    32     return true;
    33 }
    34 int bfs(int t)
    35 {
    36     int pre=0,last=0;
    37     q[last++]=(node(t,0));
    38     while(pre<last)
    39     {
    40         node top=q[pre++];
    41         if(check(top.num))
    42             return top.step;
    43         for(int i=0; i<20; i++)
    44         {
    45             int tmp=top.num;
    46             if(!(tmp&(1<<i)))continue;
    47             if(i==0)
    48             {
    49                 tmp^=(1<<0);
    50                 tmp^=(1<<1);
    51             }
    52             else if(i==19)
    53             {
    54                 tmp^=(1<<19);
    55                 tmp^=(1<<18);
    56             }
    57             else
    58             {
    59                 tmp^=(1<<i);
    60                 tmp^=(1<<(i-1));
    61                 tmp^=(1<<(i+1));
    62             }
    63             if(vis[tmp])
    64                 continue;
    65                 q[last++]=node(tmp,top.step+1);
    66         }
    67     }
    68     return false;
    69 }
    70 int main()
    71 {
    72     //freopen("data1.out","r",stdin);
    73     int s=0,tmp;
    74     for(int i=0; i<20; i++)
    75     {
    76         scanf("%d",&tmp);
    77         if(tmp)
    78         s|=(1<<i);
    79     }
    80     int ans=bfs(s);
    81     printf("%d
    ",ans);
    82     return 0;
    83 }

    高斯消元的方法:

    就是构建20个方程,每一个方程的构建就和题目中的一样,最后得出的所有x的解就是最终答案。

    AC代码:

      1 #include<iostream>
      2 #include<stack>
      3 #include<cstring>
      4 #include<iomanip>
      5 #include<stdio.h>
      6 #include<algorithm>
      7 #include<cmath>
      8 #include<queue>
      9 using namespace std;
     10 # define ll long long
     11 # define inf 0x3f3f3f3f
     12 const int mod = 21252;
     13 const int maxn = 40;
     14 int a[maxn][maxn];
     15 int equ,var;
     16 int b[maxn][maxn];
     17 int x[maxn];
     18 int free_x[maxn];
     19 int free_num;
     20 int Gass()
     21 {
     22     int max_r,col,k;
     23     free_num=0;
     24     for(k=0,col=0; k<equ&&col<var; k++,col++)
     25     {
     26         max_r=k;
     27         for(int i=k+1; i<equ; i++)
     28         {
     29             if(abs(a[i][col])>abs(a[max_r][col]))
     30                 max_r=i;
     31         }
     32         if(a[max_r][col]==0)
     33         {
     34             k--;
     35             free_x[free_num++]=col;
     36             continue;
     37         }
     38         if(max_r!=k)
     39         {
     40             for(int j=col; j<var+1; j++)
     41                 swap(a[k][j],a[max_r][j]);
     42         }
     43         for(int i=k+1; i<equ; i++)
     44         {
     45             if(a[i][col]!=0)
     46             {
     47                 for(int j=col; j<var+1; j++)
     48                     a[i][j]^=a[k][j];
     49             }
     50         }
     51     }
     52     for(int i=k; i<equ; i++)
     53         if(a[i][col]!=0)
     54         {
     55             return -1;
     56         }
     57     if(k<var)
     58         return var-k;
     59     for(int i=var-1; i>=0; i--)
     60     {
     61         x[i]=a[i][var];
     62         for(int j=i+1; j<var; j++)
     63             x[i]^=(a[i][j]&&x[j]);
     64     }
     65     return 0;
     66 }
     67 int n;
     68 void init()
     69 {
     70     memset(x,0,sizeof(x));
     71     memset(a,0,sizeof(a));
     72     equ=20;
     73     var=20;
     74     for(int i=0; i<20; i++)
     75     {
     76         a[i][i]=1;
     77         if(i>0)
     78             a[i-1][i]=1;
     79         if(i<20-1)
     80             a[i+1][i]=1;
     81     }
     82 }
     83 int solve()
     84 {
     85     int t=Gass();
     86     if(t==-1)
     87     {
     88         return t;
     89     }
     90     else if(t==0)
     91     {
     92         int  ans=0;
     93         for(int i=0; i<n*n; i++)
     94             ans+=x[i];
     95         return ans;
     96     }
     97     else
     98     {
     99         int ans=inf;
    100         int tot=(1<<t);
    101         for(int i=0; i<tot; i++)
    102         {
    103             int cnt=0;
    104             for(int j=0; j<t; j++)
    105             {
    106                 if(i&(1<<j))
    107                 {
    108                     cnt++;
    109                     x[free_x[j]]=1;
    110                 }
    111                 else
    112                 {
    113                     x[free_x[j]]=0;
    114                 }
    115             }
    116             for(int j=var-t-1; j>=0; j--)
    117             {
    118                 int dex;
    119                 for(dex=j; dex<var; dex++)
    120                     if(a[j][dex])
    121                         break;
    122                 x[dex]=a[j][var];
    123                 for(int l=dex+1; l<var; l++)
    124                 {
    125                     if(a[j][l])
    126                         x[dex]^=x[l];
    127                 }
    128                 cnt+=x[dex];
    129             }
    130             ans=min(ans,cnt);
    131         }
    132         return ans;
    133     }
    134 }
    135 int main()
    136 {
    137   // freopen("hqx.txt","r",stdin);
    138     init();
    139     int tmp;
    140     for(int i=0; i<20; i++)
    141     {
    142         scanf("%d",&tmp);
    143         a[i][20]=tmp;
    144     }
    145     int t=solve();
    146     printf("%d
    ",t);
    147     return 0;
    148 }
  • 相关阅读:
    JavaScript的valueOf和toString
    Max SPA
    SQL Server从BAK文件还原新的数据库
    SQL Server删除log文件
    为什么要监控sql语句?如何监控?
    Mac下使用zsh不执行/etc/profile文件
    MAC下快速打开指定目录(转)
    干货满满!10分钟看懂Docker和K8S(转)
    Spring Boot Metrics监控之Prometheus&Grafana(转)
    Spring Boot Actuator:健康检查、审计、统计和监控(转)
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10433617.html
Copyright © 2011-2022 走看看