Mapping the Swaps |
这题开始就引申题目的意思了,这种排序是通过多次交换不同的相邻的两个值而达到排序的目的,他要你计算的是在得到最少的交换次序达到排序的前提下,问只能是最少交换次序的排序情况有多少种,刚开始理解错了,第一次错误的理解为最小的交换次序是多少?第二次错误地理解为无特殊重复(当时我认为特殊排序就像题目说的无限循环的那种)的交换排序种类有多少种,后来通过sample最后一个case才开始确认题目的意思,因为最小的交换次序应该为1,无特殊重复的话,那么2 1 2 1 算不算呢? WA了三次过了
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=108&page=show_problem&problem=267
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define VALUE 7 6 using namespace std; 7 8 int list[VALUE]; 9 int road[VALUE*VALUE]; 10 int maxtimes, ans; 11 12 bool is_loop(int n) 13 {//判断是否为排好序,如果是则返回真,否则返回假 14 for(int i=1; i<=n-1; ++i) 15 { 16 for(int j=i+1; j<=n; ++j) 17 if(list[i] > list[j]) return false; 18 } 19 return true; 20 } 21 22 void swap(int& a, int& b) 23 { 24 int temp = a; 25 a = b; 26 b = temp; 27 return; 28 } 29 30 void Traverse(int times, int base[], int n, int num) 31 {//times 计算当前交换了多少次 , num表示上次交换的位置 32 if(is_loop(n) == true) 33 { 34 road[times]++; // road数组存储的为交换次数为 下标 的交换次数 35 return; 36 } 37 if(maxtimes <= times) return; // 如果交换次序超过了最大值就没必要继续进行 38 for(int i=1; i<n; ++i) 39 { 40 if(num != i) 41 {//这里决定了无相邻的重复的交换 42 swap(base[i], base[i+1]); 43 Traverse(times+1, base, n, i); 44 swap(base[i], base[i+1]); 45 } 46 47 } 48 } 49 50 int main() 51 { 52 53 int n, T=0; 54 while(cin>>n, n) 55 { 56 memset(road, 0, sizeof(road)); 57 for(int i=1; i<=n; ++i) 58 cin>>list[i]; 59 maxtimes = n*(n-1)/2; //个人感觉有必要考虑的就只有这么多种情况,因为此时肯定能够得到排序的可能 60 ans = 0; 61 if(!is_loop(n)) 62 { 63 Traverse(0, list, n, 0); 64 int i; 65 for(i=0; i<maxtimes && road[i] == 0; ++i) 66 ; 67 ans = road[i]; //找到第一个不为零的数,那么此时的下标就是交换次数最少的次数,里面存储 68 //是有多少种不同的情况 69 70 } 71 cout<<"There are "<<ans<<" swap maps for input data set "<<++T<<"."<<endl; 72 } 73 return 0; 74 }