HDU 4951 Multiplication table 閱讀題

鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4951

題意:給一個P進制的乘法表,行和列分別代表0~p-1,第i行第j*2+1和第j*2+2列代表的是第i行的數x和第j列的數的乘積,不過這個乘法表被人弄亂了,原來的0~p-1被映射到了一個新的0~p-1的permutation(以前在CF上看見的permutation表示1~P,所以稍有迷茫),分別代表了新的不同的數,乘法表上的數也都被映射了。現在要找出映射到了什麼新的數。

思路:毫無疑問,出現最多的數一定原來是0,而(p-1)*(p-1) = p^2-2*p+1 = p*(p-2)+1,並且只有(p-1)*(p-1)時,”十位“會出現p-2,其他相乘的”十位“數字最大也只是p-3,所以對應着行列都是p-1的數的位置,”十位“代表的一定是p-2,然後遞推着找(p-1)*(p-2)的"十位"是N-3,向下找就能找到所有數字的映射了。(2進制需要特判,因爲p-2=0)

代碼:(C++過的)

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ctype.h>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define eps 1e-10
#define INF 0x7fffffff
#define maxn 10005
#define PI acos(-1.0)
#define seed 31//131,1313
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
int a[505][1005];
int tt[505][2];
int main()
{
    int T,t=0;
    int M[505];
    while(scanf("%d",&T))
    {
        t++;
        if(T==0)
            break;
        memset(M,-1,sizeof(M));
        memset(tt,0,sizeof(tt));
        for(int i=0; i<T; i++)
            for(int j=0; j<T; j++)
            {
                scanf("%d%d",&a[i][j*2+1],&a[i][j*2+2]);
                tt[a[i][j*2+1]][0]++;
                tt[a[i][j*2+2]][1]++;
            }
        printf("Case #%d:",t);
        if(T==2)
        {
            if(tt[0][0]>tt[1][0])
                printf(" 0 1\n");
                else printf(" 1 0\n");
                continue;
        }
        int all=0,pos=0;
        for(int i=0; i<T; i++)
        {
            if(tt[i][0]+tt[i][1]>all)
            {
                all=tt[i][0]+tt[i][1];
                pos=i;
            }
        }
        M[0]=pos;
        for(int i=0;i<T;i++)
        {
            if(tt[i][0]==1)
            {
                M[T-2]=i;
                break;
            }
        }
        for(int i=0;i<T;i++)
            if(a[i][i*2+1]==M[T-2])
            {
                M[T-1]=i;
                break;
            }
        for(int i=2;i<=T-1;i++)
            M[T-i-1]=a[M[T-1]][2*M[T-i]+1];
        for(int i=0;i<T;i++)
            printf(" %d",M[i]);
        printf("\n");
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章