Gravatar
ムラサメ
积分:1497
提交:377 / 744

Pro3753  Cafe Stella

题面由wzw改编自NOIP1998 提高组 进制位


前置结论:

1.进制为n-1

2.单个字母对应的数字即为所在行两位数个数

3.单个字母对应的数字即为其在表中(除表头)出现的次数-1

证明:

1.因为n-1个不同的数,所以最少n-1进制。假设为n进制,那么一定有一个数没有出现,设为k

(1)k=0或1,1+(n-1)=10,不成立

(2)1<k≤n-1,1+(k-1)=k,不成立

同理可证大于n-1进制的情况不成立,故进制一定为n-1。

2.字母对应的数字为0…n-2,易证结论2。

3.设字母对应的数字为x,则x=0+x=1+(x-1)=2+(x-2)=... =(x-1)+1=x+0


方法

法1:

dfs暴力枚举每个字母所对应的数。

法2:(根据结论1、2)

预处理每个数的值和字母与数字的对应关系,枚举每个数检验。

法3:(根据结论3)

统计得出单个字母对应的数字,判断合法性。

代码

法1代码:

#include <bits/stdc++.h>

using namespace std;

char s[15][15][10];

int n,p,tot=0,num[15],cd[30];

bool ok[15]={0},qwq=0;

vector<int>v;

void dfs(int pt){

   if (qwq==1)return ;

   if (pt==tot+1){

       for (int i=0;i<v.size();i++){

           cd[v[i]]=num[i+1];

       }

       bool yes=0;

       for (int i=2;i<=n;i++){

           for (int j=2;j<=n;j++){

               int now=0;

               for (int k=1;k<=strlen(s[i][j]+1);k++){

                   now*=p;now+=cd[s[i][j][k]-'A'];

               }

               if (now!=cd[s[1][i][1]-'A']+cd[s[j][1][1]-'A']){

                   yes=1;break;

               }

           }

           if (yes==1)break;

       }

       if (yes==0){

           for (int i=0;i<v.size();i++){

               cout<<char(v[i]+'A')<<"="<<cd[v[i]]<<" ";

           }

           cout<<endl<<p<<endl;

           qwq=1;

       }

       return ;

   }

   for (int i=0;i<p;i++){

       if (ok[i]==0){

           num[pt]=i;

           ok[i]=1;dfs(pt+1);

           ok[i]=0;

       }

   }

   return ;

}

int main(){

   freopen ("murasame_adultxp3.in","r",stdin);

   freopen ("murasame_adultxp3.out","w",stdout);

   scanf("%d",&n);

   bool has[30]={0};

   for (int i=1;i<=n;i++){

       for (int j=1;j<=n;j++){

           scanf("%s",s[i][j]+1);

           if (s[i][j][1]!='+'){

               for (int k=1;k<=strlen(s[i][j]+1);k++){

                   if (has[s[i][j][k]-'A']==0){

                       v.push_back(s[i][j][k]-'A');tot++;

                       has[s[i][j][k]-'A']=1;

                   }

               }

           }

       }

   }

   for (p=tot;p<=10;p++){

       memset(ok,0,sizeof(ok));

       dfs(1);

   }

   if (qwq==0){

       cout<<"FccKcuf"<<endl;

   }

   return 0;

}

法2代码:

#include<bits/stdc++.h>

using namespace std;

inline int read()

{

   char ch=getchar();

   int f=1,x=0;

   while (ch<'0' || ch>'9')

   {

       if (ch=='-') f=-1;

       ch=getchar();

   }

   while (ch>='0' && ch<='9')

   {

       x=x*10+ch-'0';

       ch=getchar();

   }

   return f*x;

}

int n,ans[15],mp[26];

char s[15][15][3];

inline bool check(int x,int y) //检验 (x,y)

{

   int sum=ans[x]+ans[y]; //和

   int cur=s[x][y][1]-'A'; //处理十位

   if (sum>=n-1 && mp[cur]!=1) return 0; //如果和 >=n-1 但没有进位

   if (sum>=n-1) sum-=n-1,cur=s[x][y][2]-'A'; //处理个位

   if (mp[cur]!=sum) return 0; //不相等

   return 1;

}

signed main()

{

   n=read();

   for (int j=1;j<=n;j++) scanf("%s",s[1][j]+1);

   for (int i=2;i<=n;i++)

   {

       int cnt=0;

       for (int j=1;j<=n;j++)

       {

           scanf("%s",s[i][j]+1);

           cnt+=strlen(s[i][j]+1)>=2;

       }

       ans[i]=cnt;

       mp[s[i][1][1]-'A']=cnt;

   }

   for (int i=2;i<=n;i++) for (int j=2;j<=n;j++) if (!check(i,j)) return 0&puts("ERROR!");

   for (int i=2;i<=n;i++) printf("%c=%d ",s[i][1][1],ans[i]);

   return !printf("\n%d",n-1);

}

法3代码:

#include<bits/stdc++.h>

using namespace std;

char a[10][10][5];

int n,g[300];

int main(){

   freopen("murasame_adultxp3.in","r",stdin);

   freopen("murasame_adultxp3.out","w",stdout);

   ios::sync_with_stdio(0);

   cin.tie(0);

   cout.tie(0);

   cin>>n;

   for(int i=1;i<=n;i++){

       for(int j=1;j<=n;j++){

           cin>>a[i][j];

       }

   }

   for(int i=2;i<=n;i++){

       for(int j=2;j<=n;j++){

           if(strlen(a[i][j])==1){

               g[a[i][j][0]]++;

           }

       }

   }

   for(int i=2;i<=n;i++){

       for(int j=2;j<=n;j++){

           int x=g[a[i][1][0]]-1,y=g[a[1][j][0]]-1;

           int z=0;

           int l=strlen(a[i][j]);

           for(int k=0;k<=l-1;k++){

               int val=g[a[i][j][k]]-1;

               z=z*(n-1)+val;

           }

           if(x+y!=z){

               cout<<"FccKcuf"<<endl;

               return 0;

           }

       }

   }

   for(int i=2;i<=n;i++){

       cout<<a[1][i][0]<<"="<<g[a[1][i][0]]-1<<" ";

   }

   cout<<endl<<n-1<<endl;

   return 0;

}



2022-09-14 20:13:29    
我有话要说
暂无人分享评论!