SRM 397(1-250pt)

题意:对于一个长度n的数列(由1-n组成,n <= 8),每次操作可以reverse k个连续的数。问最少多少次操作可以将该数列转化成递增的数列。

解法:就是一个BFS。只是由于最开始学习BFS时写法很复杂,所以直到现在也觉得BFS不好写。然后就在想还有没有别的方法,然后时间就浪费了...最后还是写了个比较冗杂的BFS,150+score。看了官方题解的BFS,真是学习了...一方面是BFS的写法搓,另一方面是不会用C++内置的reverse函数。

tag:BFS

我的代码:

  1 // BEGIN CUT HERE
  2 /*
  3  * Author:  plum rain
  4  * score :
  5  */
  6 /*
  7 
  8  */
  9 // END CUT HERE
 10 #line 11 "SortingGame.cpp"
 11 #include <sstream>
 12 #include <stdexcept>
 13 #include <functional>
 14 #include <iomanip>
 15 #include <numeric>
 16 #include <fstream>
 17 #include <cctype>
 18 #include <iostream>
 19 #include <cstdio>
 20 #include <vector>
 21 #include <cstring>
 22 #include <cmath>
 23 #include <algorithm>
 24 #include <cstdlib>
 25 #include <set>
 26 #include <queue>
 27 #include <bitset>
 28 #include <list>
 29 #include <string>
 30 #include <utility>
 31 #include <map>
 32 #include <ctime>
 33 #include <stack>
 34 
 35 using namespace std;
 36 
 37 #define CLR(x) memset(x, 0, sizeof(x))
 38 #define CLR1(x) memset(x, -1, sizeof(x))
 39 #define PB push_back
 40 #define SZ(v) ((int)(v).size())
 41 #define ALL(t) t.begin(),t.end()
 42 #define zero(x) (((x)>0?(x):-(x))<eps)
 43 #define out(x) cout<<#x<<":"<<(x)<<endl
 44 #define tst(a) cout<<#a<<endl
 45 #define CINBEQUICKER std::ios::sync_with_stdio(false)
 46 
 47 typedef vector<int> VI;
 48 typedef vector<string> VS;
 49 typedef vector<double> VD;
 50 typedef pair<int, int> pii;
 51 typedef long long int64;
 52 
 53 const double eps = 1e-8;
 54 const double PI = atan(1.0)*4;
 55 const int maxint = 2139062143;
 56 
 57 struct nod{
 58     VI b;
 59     int d;
 60 };
 61 
 62 VI b;
 63 int n;
 64 nod an[1000000];
 65 set<VI> st;
 66 VI ans;
 67 
 68 
 69 int BFS(int k)
 70 {
 71     if (b == ans) return 0;
 72     st.erase(ALL(st));
 73     int l = 0, r = 0;
 74     VI ttt;
 75     nod tt; tt.d = 1;
 76     for (int i = 0; i+k <= n; ++ i){
 77         ttt = b;
 78         for (int j = i, t = i+k-1; j < t; ++ j, -- t)
 79             swap(ttt[j], ttt[t]);
 80         tt.b = ttt;
 81         if (!st.count(ttt)){
 82             an[r++] = tt;
 83             st.insert(ttt);
 84         }
 85     }
 86 
 87     while (l < r){
 88         nod tmp = an[l++];
 89         if (tmp.b == ans) return tmp.d;
 90         ++ tmp.d;
 91         for (int i = 0; i+k <= n; ++ i){
 92             ttt = tmp.b;
 93             for (int j = i, t = i+k-1; j < t; ++ j, -- t)
 94                 swap(ttt[j], ttt[t]);
 95             if (!st.count(ttt)){
 96                 an[r].b = ttt;
 97                 an[r++].d = tmp.d;
 98                 st.insert(ttt);
 99             }
100         }
101     }
102     return -1;
103 }
104 
105 class SortingGame
106 {
107     public:
108         int fewestMoves(vector <int> B, int k){
109             b = B; n = b.size();
110             ans.clear();
111             for (int i = 1; i <= n; ++ i)
112                 ans.PB(i);
113             return BFS (k);
114         }
115         
116 // BEGIN CUT HERE
117     public:
118     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); }
119     private:
120     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
121     void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
122     void test_case_0() { int Arr0[] = {1,2,3}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 3; int Arg2 = 0; verify_case(0, Arg2, fewestMoves(Arg0, Arg1)); }
123     void test_case_1() { int Arr0[] = {3,2,1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 3; int Arg2 = 1; verify_case(1, Arg2, fewestMoves(Arg0, Arg1)); }
124     void test_case_2() { int Arr0[] = {5,4,3,2,1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; int Arg2 = 10; verify_case(2, Arg2, fewestMoves(Arg0, Arg1)); }
125     void test_case_3() { int Arr0[] = {3,2,4,1,5}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 4; int Arg2 = -1; verify_case(3, Arg2, fewestMoves(Arg0, Arg1)); }
126     void test_case_4() { int Arr0[] = {7,2,1,6,8,4,3,5}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 4; int Arg2 = 7; verify_case(4, Arg2, fewestMoves(Arg0, Arg1)); }
127 
128 // END CUT HERE
129 
130 };
131 
132 // BEGIN CUT HERE
133 int main()
134 {
135 //    freopen( "a.out" , "w" , stdout );    
136     SortingGame ___test;
137     ___test.run_test(-1);
138        return 0;
139 }
140 // END CUT HERE
View Code

官方题解推荐代码:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <sstream>
 4 #include <vector>
 5 #include <cmath>
 6 #include <map>
 7 #include <queue>
 8 using namespace std;
 9 typedef vector<int> VI;
10  
11 struct SortingGame {
12   int fewestMoves(vector<int> board, int k) {
13     map<VI, int> dist;
14     dist[board] = 0;
15  
16     queue<VI> Q;
17     Q.push(board);
18  
19     int i, N = board.size();
20  
21     while (!Q.empty()) {
22       VI u = Q.front(); Q.pop();
23       int d = dist[u];
24  
25       for (i = 1; i < N; i++)
26         if (u[i-1] > u[i]) break;
27       if (i == N) return d;
28  
29       for (i = 0; i + k <= N; i++) {
30         VI w = u;
31         reverse(w.begin() + i, w.begin() + i + k);
32         if (dist.count(w) == 0) {
33           dist[w] = d + 1;
34           Q.push(w);
35         }
36       }
37     }
38  
39     return -1;    
40   }
41 };
View Code

 

转载于:https://www.cnblogs.com/plumrain/p/srm_397.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值