标签:
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2420 Accepted Submission(s): 511
1 #include<iostream> 2 #include <cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include <string>//定义string类型的变量是需要头文件 6 #include<queue> 7 using namespace std; 8 char a[10],b[10]; 9 int visit[50000]; 10 int f[10]= {1,1,2,6,24,120,720,5040}; //1-7的阶层,康托展开需要用到 11 string str[500000]; //存放康托展开的变换过程 12 struct node 13 { 14 char num[8];//记录当前字符串 15 int ct;//记录康托值 16 }; 17 node node1,node2; 18 19 void way(int k)//将12345678经过0,1,2三种变换方式 20 { 21 if(k==0)//87654321 22 { 23 for(int i=0; i<4; i++) 24 { 25 node2.num[i]=node1.num[7-i]; 26 node2.num[i+4]=node1.num[3-i]; 27 } 28 } 29 else if(k==1)//41236785 30 { 31 node2.num[0]=node1.num[3]; 32 node2.num[7]=node1.num[4]; 33 for(int i=1; i<4; i++) 34 { 35 node2.num[i]=node1.num[i-1]; 36 node2.num[i+3]=node1.num[i+4]; 37 } 38 } 39 else//17245368 40 { 41 node2.num[0]=node1.num[0]; 42 node2.num[1]=node1.num[6]; 43 node2.num[2]=node1.num[1]; 44 node2.num[3]=node1.num[3]; 45 node2.num[4]=node1.num[4]; 46 node2.num[5]=node1.num[2]; 47 node2.num[6]=node1.num[5]; 48 node2.num[7]=node1.num[7]; 49 } 50 } 51 //康托展开的公式是 X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,ai为当前未出现的元素中是排在第几个(从0开始) 52 int kangtuo(char ch[]) //计算康托展开的数字,方法详见“康托展开”博客 53 { 54 int s=0,w; 55 for(int i=0; i<8; i++) 56 { 57 w=0; 58 for(int j=i+1; j<8; j++) 59 { 60 if(ch[j]<ch[i]) 61 w++; 62 } 63 s+=w*f[7-i]; 64 } 65 return s; 66 } 67 void bfs() 68 { 69 70 int n; 71 char c; 72 queue<node> q; 73 while(!q.empty()) 74 q.pop(); 75 76 strcpy(node1.num,"12345678");//起始状态虽然不是12345678,但是可以把它看做12345678 77 node1.ct=0;//初始康托值为0 78 memset(visit,0,sizeof(visit)); 79 visit[0]=1; 80 str[0]=""; 81 q.push(node1); 82 while(!q.empty()) 83 { 84 node1=q.front(); 85 q.pop(); 86 for(int i=0; i<3; i++) 87 { 88 way(i);//变换后的字符记录在node2.num上 89 n=kangtuo(node2.num);//此时的康托值 90 if(!visit[n])//通过判断康托值是否出现以此记录这个串是否出现 91 { 92 visit[n]=1;//这个康托值标记为已出现 93 c=‘A‘+i; //变换的方案 94 node2.ct=n;//保存当前串的康托值 95 str[n]=str[node1.ct]+c; //记录变换过程 96 q.push(node2); 97 } 98 } 99 } 100 } 101 int main() 102 { 103 char ch[10]; 104 int nums; 105 bfs();//预处理打表 106 while(~scanf("%s%s",a,b)) 107 { 108 for(int i=0; i<8; i++) 109 { 110 ch[a[i]-‘0‘]=i+1+‘0‘;//建立对应关系,记录起始数据每个数的位置,必须借用ch[]保存 111 } 112 for(int j=0; j<8; j++) 113 { 114 b[j]=ch[b[j]-‘0‘];//置换,利用位置变换形成新的字符串 115 } 116 // for(int k=0;k<8;k++)//测试 117 // printf("%d",b[k]); 118 nums=kangtuo(b);//计算康托展开的数 119 // printf("%d\n",nums);//测试 120 cout<<str[nums]<<endl; //根据康托展开记录的数字查找 121 } 122 }
标签:
原文地址:http://www.cnblogs.com/dshn/p/4948431.html