題解 P1013 【進制位】

------------恢復內容開始------------
別說這是個人第一篇題解c++

AC記錄優化

13ms / 688.00KB ,其實能夠說還算快的吧。spa


題目再次複述code

1.字母都不一樣
2.在限定進制內加減法
3.第一行第一列字母排列相等

有些人這麼想,枚舉每個字母,不過--blog

正常人應該能夠明白進製爲nget

仔細分析一下,能夠發現每一個字母\(ch\)\(0 \leq ch \leq n-1\)it

那不就是迎刃而解接了嗎?class

  1. 每一個字母依次賦與\(0\)\((n-1)\)sed

  2. 依次判斷是否符合im

note:本人碼風可能有點醜

#include<bits/stdc++.h>
#define INF 1e9
using namespace std;
const int N=12,M=100;
char s[N][N][M];// s[i][j][k]爲第i行第j列的第k個字母
int num[M];
int n;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=26;i++) num[i]=INF;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%s",s[i][j]+1);
    for(int i=2;i<=n;i++) num[s[1][i][1]-'A'+1]=i-2;  //每一個字母一側賦值
    for(int i=2;i<=n;i++)
        for(int j=2;j<=n;j++){//兩兩配對
            int combine1=num[s[1][j][1]-'A'+1];
            int combine2=num[s[i][1][1]-'A'+1];
            int len=strlen(s[i][j]+1);

            int p1=0,t=1;
            for(int k=1;k<=len;k++){
                p1+=num[s[i][j][len-k+1]-'A'+1]*t;
                t*=(n-1);
            }//兩數之和轉爲n進制

            int p2=combine1+combine2//字母權相加
            if(p1!=p2){
                puts("ERROR!");
                return 0;
            }
        }
    for(int i=2;i<=n;i++){
        printf("%c=%d",s[1][i][1],num[s[1][i][1]-'A'+1]);//輸出
        if(i!=n) printf(" ");
    }
    printf("\n%d\n",n-1);
    return 0;
}

尚未結束。。。
P1013 進制位

是什麼緣由呢?

呵呵。

誰說的必須依次賦值?

每一個字母依次賦與\(0\)\((n-1)\)

但不能重複哦!

#include<bits/stdc++.h>
#define INF 1e9
using namespace std;
const int N=12,M=100;
int n;
char s[N][N][M];
int num[M];//第i個字母的賦值
bool used[M]; //i數是否用過
int sol(int t){
    if(t>n){
        bool f=false;
        for(int i=2;i<=n;i++){
            for(int j=2;j<=n;j++){
                int combine1=num[s[1][j][1]-'A'+1];
                int combine2=num[s[i][1][1]-'A'+1];
                int len=strlen(s[i][j]+1);
    
                int p1=0,t=1;
                for(int k=1;k<=len;k++){
                    p1+=num[s[i][j][len-k+1]-'A'+1]*t;
                    t*=(n-1);
                }
    
                int p2=combine1+combine2;
                if(p1!=p2){
                    f=true;
                    break;
                }//上段就是比較
            }
            if(f) break;
        }
        if(!f){
            for(int i=2;i<=n;i++){
                printf("%c=%d",s[1][i][1],num[s[1][i][1]-'A'+1]);
                if(i!=n) printf(" ");
            }
            printf("\n%d\n",n-1);
            return -1;
        }//上段就是輸出
        return 0;
    }
    for(int i=0;i<n-1;i++) if(!used[i]){
        used[i]=true;
        num[s[1][t][1]-'A'+1]=i;//放進去
        int nw=sol(t+1);
        if(nw==-1) return -1;//回朔
        num[s[1][t][1]-'A'+1]=INF;
        used[i]=false;
    }
    return 0;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=26;i++) num[i]=INF;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%s",s[i][j]+1);
    memset(used,0,sizeof(used));
    int nw=sol(2);//結束了嗎?
    if(nw!=-1) puts("ERROR!");
    return 0;
}

終於作完了,分析一下時間複雜度

\(O(n!·n^2·Len) (n \leq 9)\)

(我長度算的3)

再加上一些雜七雜八的優化,\(break\),穩穩的就\(AC\)了。
------------恢復內容結束------------

相關文章
相關標籤/搜索