Multiplication table
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 491 Accepted Submission(s): 230
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.
For example, the following is a multiplication table in base 4:
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:
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.
Input
There are multiple test cases, terminated by a line "0".
For each test case, the first line contains one integer p(2<=p<=500).
In following p lines, each line contains 2*p integers. The (2*j+1)-th number x and (2*j+2)-th number y in the i-th line indicates equation i*j=xy in the shuffled multiplication table.
Warning: Large IO!
For each test case, the first line contains one integer p(2<=p<=500).
In following p lines, each line contains 2*p integers. The (2*j+1)-th number x and (2*j+2)-th number y in the i-th line indicates equation i*j=xy in the shuffled multiplication table.
Warning: Large IO!
Output
For each case, output one line.
First output "Case #k:", where k is the case number counting from 1. The following are p integers, indicating the permutation number 0..p-1 mapped into.
First output "Case #k:", where k is the case number counting from 1. The following are p integers, indicating the permutation number 0..p-1 mapped into.
Sample Input
4 2 3 1 1 3 2 1 0 1 1 1 1 1 1 1 1 3 2 1 1 3 1 1 2 1 0 1 1 1 2 1 3 0
Sample Output
Case #1: 1 3 2 0题意:对于一个p进制的乘法表。现在将p进制的0,1,2....p-1映射成0到p-1的另一个排列,并且将乘法表0到p-1的相对顺序打乱。现在给你打乱以后的乘法表,让你求出每个数映射成了那个数?题解:解法很简单,但是不容易想到。首先0可以很容易确定出来,因为乘法表中只有0的那一行和那一列全是0。对于剩下的数字,1对于的那行十位只会出现0。对于2对应的那行,十位只会出现0,1,并且都会出现。那么对于i对应的那行,十位只会出现0,1,,,i-1,并且都会出现。简单的证明一下,对于第i行,十位最大是i*(p-1)那个数,显然是i-1,最小显然是0,由于i<p,所以对于0到i-1的每一个十位,都会出现。代码如下:(由于题目提示输入数据很多,所以用了输入输出优化)#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<vector> #include<cmath> #include<map> #define nn 550 using namespace std; pair<int,int> a[nn][nn]; map<int,int>ma; int p; bool use[nn]; inline int read() { char ch; bool flag=false; int re=0; while(!(((ch=getchar())>='0'&&(ch<='9'))||(ch=='-'))); if(ch!='-') { re*=10; re+=ch-'0'; } else flag=true; while((ch=getchar())>='0'&&(ch<='9')) { re*=10; re+=ch-'0'; } if(flag) re=-re; return re; } inline void write(int x) { if(x<0) { putchar('-'); x=-x; } if(x>=10) { write(x/10); } putchar(x%10+'0'); } int main() { int i,j; int cas=1; while(1) { p=read(); if(p==0) break; ma.clear(); for(i=0;i<p;i++) { for(j=0;j<p;j++) { a[i][j].first=read(); a[i][j].second=read(); } } printf("Case #%d: ",cas++); for(i=0;i<p;i++) { for(j=0;j<p;j++) { if(a[i][j].first!=a[i][j].second) break; if(j&&a[i][j]!=a[i][j-1]) break; } if(j==p) { ma[0]=i; break; } } int ix; for(i=0;i<p;i++) { if(ma[0]==i) continue; memset(use,false,sizeof(use)); for(j=0;j<p;j++) { use[a[i][j].first]=true; } ix=0; for(j=0;j<p;j++) { if(use[j]) ix++; } ma[ix]=i; } for(i=0;i<p;i++) { write(ma[i]); printf("%c",i==p-1?'\n':' '); } } return 0; }