zoukankan      html  css  js  c++  java
  • luogu1092 虫食算

    题目链接:https://www.luogu.org/problem/show?pid=1092

    解:

    我真的交了好多遍。。

    开始,用getchar()一个个字母读入,0分。。。

    改成scanf(),70,并且在70的道路上一发不可收拾。。。

    后来看了别人的代码才发现,原来我们的枚举是要进行优化的。。。

    解:

    70分做法:先枚举每个字母代表的数字,然后枚举一个,判断一次,如果一列上的三个字母都有代表的数字了,就判断合不合法,枚举所有的列。最后枚举完后检查一遍。

    100分做法:在上一个做法的情况下我们不要从‘A’~‘Z’来一个个枚举代表的数字,而是按照输入的顺序来,我们开一个数组,一列列扫过三个字符串,如果这个字符没在数组里,就把它加进去。最后按照数组中的字母的顺序来进行枚举。很显然按这个枚举方式,更容易在判断的时候时间较短地找到错误,因为两个都是一列列扫的。至于从前往后还是从后往前,就需要与判断时候扫的顺序一致。

    程序:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    using namespace std;
    int n,num[30],a[30],b[30],c[30],cnt,po[30];
    char a1[30],b1[30],c1[30];
    bool vis[30],bl[100];
    void write()
    {
      for (int i=0;i<=n-2;i++)
      printf("%d ",num[i]);
      if (n!=0) printf("%d
    ",num[n-1]);
      exit(0);
    }
    bool check()
    {
      for (int i=n;i>=1;i--)
      if ((num[a[i]]!=-1)&&(num[b[i]]!=-1)&&(num[c[i]]!=-1)
      &&(((num[a[i]]+num[b[i]])%n)!=num[c[i]])&&(((num[a[i]]+num[b[i]]+1)%n)!=num[c[i]])) return false;
      return true;
    }
    bool check2()
    {
      int ef=0;
      for (int i=n;i>=1;i--)
      {
          int l=num[a[i]]+num[b[i]]+ef;
          if ((l%n)!=num[c[i]]) return false;
          ef=l/n;
      }
      return true;
    }
    void dfs(int now)
    {
      if ((num[a[1]]+num[b[1]])>n-1) return;
      if (!check()) return; 
      if (now==n) {if (check2()) write();}
      for (int j=n-1;j>=0;j--)
       if (!vis[j])
       {
            num[po[now]]=j;
            vis[j]=true;
         dfs(now+1);
            vis[j]=false;
            num[po[now]]=-1;
       }
    }
    int main()
    {
      scanf("%d",&n);
      scanf("%s%s%s",a1,b1,c1);
      char ch;
      for (int i=0;i<=n;i++) num[i]=-1;
      for (int i=1;i<=n;i++)
      {
          a[i]=a1[i-1]-'A';
          b[i]=b1[i-1]-'A';
          c[i]=c1[i-1]-'A';
      }
      for (int i=n-1;i>=0;i--)
      {  
       if (!bl[a1[i]]) {po[cnt++]=a[i+1];bl[a1[i]]=true;}
       if (!bl[b1[i]]) {po[cnt++]=b[i+1];bl[b1[i]]=true;}
       if (!bl[c1[i]]) {po[cnt++]=c[i+1];bl[c1[i]]=true;}
       if (cnt==n) break;
      }
      dfs(0);
      return 0;
    }
  • 相关阅读:
    PCL点云
    unity碰撞,刚体笔记
    动画剪辑 状态配置 脚本编写2
    unity中动画剪辑,状态机关系配置,脚本编写方式1
    unity给物体着色加纹理图 material(材质)
    C++/Java小白解Leetcode题,发现了知识盲区……
    NLP之统计句法分析(PCFG+CYK算法)
    Java:基于TCP协议网络socket编程(实现C/S通信)
    Java实现:抛开jieba等工具,写HMM+维特比算法进行词性标注
    Java多线程技术:实现多用户服务端Socket通信
  • 原文地址:https://www.cnblogs.com/2014nhc/p/6698008.html
Copyright © 2011-2022 走看看