虫食算

                                                                                                                                                                                         这里是题目呀

    因为太懒了所以不概括题意了(懒得调格式 copy下来很丑)

    思路:   其实最朴素的很好想啦

     就是枚举每个字母所代表的数 然后check

                  优化就是尽量从低位开始赋值 这样可以更早检验并排除错误答案

                  这里一个预处理就可以啦

                  数组有很多 一定不能晕了

 

     However,我的代码仍然有少数超时的点

     So 待修正完善的 CODE

#include<iostream>
#include<cstdio>
#include<string>
#include<cstdlib>
#define go(i,a,b) for(register int i=a;i<=b;i++)
#define goo(i,a,b) for(register int i=a;i>=b;i--)
#define M 30
using namespace std;
int read()
{
  int x=0,y=1;char c=getchar();
  while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();}
  while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
  return x*y;
}
int n,a[3][M],b[M],cnt,ccnt,n_ans[M],f_ans[M];
bool fg[M];
string s;
void putin()
{
  n=read();
  go(i,0,2)
    {cin>>s; go(k,1,n) a[i][k]=s[n-k]-'A'+1;}
  go(i,1,n) {
      if(!b[a[0][i]]) b[a[0][i]]=++cnt;
      if(!b[a[1][i]]) b[a[1][i]]=++cnt;
      if(!b[a[2][i]]) b[a[2][i]]=++cnt;
  }
  go(i,0,2) go(j,1,n) a[i][j]=b[a[i][j]];
}
bool ck()
{
  int x,y,z;
  go(i,1,n) {
      x=n_ans[a[0][i]];y=n_ans[a[1][i]];z=n_ans[a[2][i]];
      if(x&&y&&z&&((x+y)%n!=z)&&((x+y+1)%n!=z)) return 0;
    }
  return 1;
}
bool f_ck()
{
  int x,y,z,k=0;
  go(i,1,n) {
      x=n_ans[a[0][i]];y=n_ans[a[1][i]];z=n_ans[a[2][i]];
      if((x+y+k)%n!=z) return 0;
      k=(x+y+k)/n;
    }
  if(k) return 0;
  return 1;
}
void print()
{
  go(i,1,n-1) printf("%d ",f_ans[b[i]]);
  printf("%d",f_ans[b[n]]);
}
void dfs(int nw)
{
  if(nw==n) {
    if(f_ck())
      {go(i,1,n) f_ans[i]=n_ans[i];print();exit(0);}
    else return ;
  }
  if(!ck()) return ;
  goo(i,n-1,0) {
      if(!fg[i])
        {fg[i]=1;n_ans[nw+1]=i;dfs(nw+1);n_ans[nw+1]=0;fg[i]=0;}
    }
  return ;
}
int main()
{
  //freopen("alpha.in","r",stdin);
  //freopen("alpha.out","w",stdout);
  putin();
  dfs(0);
  return 0;
}
TLE Code

 

      Then 再附上我以前写的AC CODE

 

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int n;
int a[30],b[30],c[30];//下标为位数(1~n-1) 从右往左 值为未知数(1~n-1)
int p[30];
void read(int x[])
{
    char ch;
    for(int i=n;i>=1;i--)
    {
        ch=getchar();
        while(ch<'A'||ch>'Z') ch=getchar();
        x[i]=ch-'A'+1;
    }
}
int d[30];//下标为字母转换成的数字 相当于未知数吧 值为未知数的值(0~n-1)
int used[30];//下标为具体值
bool Judge()
{
    for(int i=1;i<=n;i++)  //第i位
    {
        int x1=a[i],y1=b[i],z1=c[i];
        if(d[x1]==-1||d[y1]==-1||d[z1]==-1) continue ;
        if(((d[x1]+d[y1])%n!=d[z1])&&((d[x1]+d[y1]+1)%n!=d[z1])) return 0;
    }
    return 1;
}
bool F_Judge()
{
    int y=0;
    for(int i=1;i<=n;i++)
    {
        int x1=a[i],y1=b[i],z1=c[i];
        if((d[x1]+d[y1]+y)%n!=d[z1]) return 0;
        y=(d[x1]+d[y1]+y)/n;
    }
    return 1;
}
void print()
{
    for(int i=1;i<=n;i++) printf("%d ",d[i]);
}
void dfs(int x)
{
    if(x>n)
    {
        if(F_Judge()) {print();exit(0);}
        return ;
    }
    for(int i=n-1;i>=0;i--) //i:具体值
    {
        if(used[i]) continue;
        d[p[x]]=i;
        if(!Judge()) continue;
        used[i]=1;
        dfs(x+1);
        used[i]=0;
    }
    d[p[x]]=-1;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) d[i]=-1;
    read(a);read(b);read(c);
    int num=0;
    for(int i=1;i<=n;i++)
    {
        if(!used[a[i]]) {p[++num]=a[i];used[a[i]]=1;}
        if(!used[b[i]]) {p[++num]=b[i];used[b[i]]=1;}
        if(!used[c[i]]) {p[++num]=c[i];used[c[i]]=1;}
    }
    for(int i=1;i<=n;i++) used[i]=0;
    dfs(1);
    return 0;
}
AC Code

 

posted @ 2019-01-22 21:21  DTTTTTTT  阅读(202)  评论(1编辑  收藏  举报