2014 Multi-University Training Contest 8 1007 hdu 4951 Multiplication table


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




Problem Description
Teacher Mai has a multiplication table in base p.

For example, the following is a multiplication table in base 4:

* 0 1 2 3
0 00 00 00 00
1 00 01 02 03
2 00 02 10 12
3 00 03 12 21


But a naughty kid maps numbers 0..p-1 into another permutation and shuffle the multiplication table.

For example Teacher Mai only can see:

1*1=11 1*3=11 1*2=11 1*0=11
3*1=11 3*3=13 3*2=12 3*0=10
2*1=11 2*3=12 2*2=31 2*0=32
0*1=11 0*3=10 0*2=32 0*0=23


Teacher Mai wants you to recover the multiplication table. Output the permutation number 0..p-1 mapped into.

It's guaranteed the solution is unique.
 
 

Sample Output
  
  
Case #1: 1 3 2 0
 



  题意

    通过映射,例如样例,1->0,3->1,2->2,0->3,再通过行列变换,样例,第1行移至0行,3行移至1行...... 就形成了p进制的乘法表

  题解

      把0特判,0的那行所有数字都为0,映射后一行的所有的数字都相同,1与所有数相乘十位只可能为0,2与所有数相乘十位只可能为0,1......n与所有数相乘十位只有n-1种数,通过判断十位出现的不同数的个数,就可以判断其他数的映射关系。

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[510][510]; //第i行数的十位数的个数
int c[520];//第j行十位数种类数是i
int main()
{
    int n,ca=1;
    while(~scanf("%d",&n))
    {
        if(n==0)
        break;
        memset(a,0,sizeof(a));
        int x=0;
        int y=0;
        int temp=-1;
        int sign=1;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            if(x==y&&sign)//先把0特判
            temp=x;
            a[i][x]++;
            for(int j=1;j<n;j++)
            {
                scanf("%d%d",&x,&y);
                if(sign)
                {
                    if(x==y&&x==temp)
                    ;
                    else
                    {
                    temp=-1;
                    }
                }
                if(a[i][x]==0)
                {
                 a[i][x]++; //第i行十位数的个数


                }
            }
            if(sign&&temp!=-1)
            {
                sign=0;
            }
        }
        for(int i=0;i<n;i++)
        {
            int ans=0;
            for(int j=0;j<n;j++)
            {
                if(a[i][j]) //判断十位数有几种
                ans++;
            }
            if(i!=temp)
            {
                c[ans]=i; //有ans种十位数所对应的行
            }
        }
        printf("Case #%d:",ca++);
        printf(" %d",temp);
        for(int i=1;i<n;i++)
        printf(" %d",c[i]);
        printf("\n");
    }
    return 0;
}






  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值