SRM 441(1-250pt, 1-500pt)

DIV1 250pt

题意:用数组A表示置换,由该置换得到数组B(B[0] = 0, B[i] = A[B[i-1]])。给定A,求一个A',使得由A'得到的B为单循环置换且A'与A的差距最小。定义A与A'的差距为,有多少个i满足A[i] != A'[i]。返回最小差距值。A.size() <= 50。

解法:要得到的B为单循环置换,则A'也为单循环置换。如果置换A含有t个循环节,if (t==1)差距为0,否则最小差距为t,原因是可以通过交换某两个数的位置,使得两个循环变为1个循环。

tag:math, permutation

 1 // BEGIN CUT HERE
 2 /*
 3  * Author:  plum rain
 4  * score :
 5  */
 6 /*
 7 
 8  */
 9 // END CUT HERE
10 #line 11 "PerfectPermutation.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 clr0(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<<" "
45 #define tst1(a) cout<<#a<<endl
46 #define CINBEQUICKER std::ios::sync_with_stdio(false)
47 
48 typedef vector<int> vi;
49 typedef vector<string> vs;
50 typedef vector<double> vd;
51 typedef pair<int, int> pii;
52 typedef long long int64;
53 
54 const double eps = 1e-8;
55 const double PI = atan(1.0)*4;
56 const int inf = 2139062143 / 2;
57 
58 class PerfectPermutation
59 {
60     public:
61         bool v[100];
62         int reorder(vector <int> p){
63             clr0 (v);
64             int cnt = 0;
65             for (int i = 0; i < sz(p); ++ i) if (!v[p[i]]){
66                 int t = p[i];
67                 while (!v[t])
68                     v[t] = 1, t = p[t];
69                 ++ cnt;
70             }
71             if (cnt == 1) return 0;
72             return cnt;
73         }
74         
75 // BEGIN CUT HERE
76     public:
77     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(); }
78     private:
79     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(); }
80     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; } }
81     void test_case_0() { int Arr0[] = {2, 0, 1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 0; verify_case(0, Arg1, reorder(Arg0)); }
82     void test_case_1() { int Arr0[] = {2, 0, 1, 4, 3}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(1, Arg1, reorder(Arg0)); }
83     void test_case_2() { int Arr0[] = {2, 3, 0, 1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(2, Arg1, reorder(Arg0)); }
84     void test_case_3() { int Arr0[] = {0, 5, 3, 2, 1, 4}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 3; verify_case(3, Arg1, reorder(Arg0)); }
85     void test_case_4() { int Arr0[] = {4, 2, 6, 0, 3, 5, 9, 7, 8, 1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 5; verify_case(4, Arg1, reorder(Arg0)); }
86 
87 // END CUT HERE
88 
89 };
90 
91 // BEGIN CUT HERE
92 int main()
93 {
94 //    freopen( "a.out" , "w" , stdout );    
95     PerfectPermutation ___test;
96     ___test.run_test(-1);
97        return 0;
98 }
99 // END CUT HERE
View Code

 

DIV1 500pt

题意:在一个无向图G中,可以做这样一种操作:

   选取一组点(A,B,C,D),其中AB有边直接连接,CD有边直接连接,AC,AD,BC,BD无直连边。那么毁坏AB,CD相连的边,并重新连接AC和BD,或者重新连接AD和BC。

   对于一张给定图,问最少多少次操作才能使其变为连通图,如果不能变为连通图输出-1。

解法:我YY了一个结论。。。如果G中已经连的边数<G中的点数-1,则输出-1;如果存在某个连通块点数为1,输出-1;否则输出连通块的数目-1。

   下面是证明:称题目所给操作为L操作。

   由题可以推出以下几点:1、L操作不改变边的数量;2、如果去除了AB相连的边,AB还是在同一个连通块中,即AB在某个环上,则L操作可以将两个连通块变为一个;3、如果某个连通块的边数>=点数,即该连通块含有环,那么一定能够通过L操作将它与另一个含有边的连通块融合为一个。而连通块含有边的条件就是点数大于1;4、对于连通块的数目,一次L操作要么不改变连通块的数目,要么使连通快的数目减1。

   由1,2,3可知,当G中边数>=点数且不存在点数为1的连通块时,可通过不断进行L操作来将将连通块数目减少到1,即此时一定可以将G变为连通图。

   由4可知,每次L操作只能使连通块数目减1,则一定需要连通块数目-1次L操作才能将G变为联通图。所以,问题得证。

Ps:官方题解貌似使用记录所有联通块的点数和边数,不断合并联通块的方式来做的。我的代码比它的简单多了^ ^。

tag:think, graph, good

  1 // BEGIN CUT HERE
  2 /*
  3  * Author:  plum rain
  4  * score :
  5  */
  6 /*
  7 
  8  */
  9 // END CUT HERE
 10 #line 11 "StrangeCountry.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 clr0(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<<" "
 45 #define tst1(a) cout<<#a<<endl
 46 #define CINBEQUICKER std::ios::sync_with_stdio(false)
 47 
 48 typedef vector<int> vi;
 49 typedef vector<string> vs;
 50 typedef vector<double> vd;
 51 typedef pair<int, int> pii;
 52 typedef long long int64;
 53 
 54 const double eps = 1e-8;
 55 const double PI = atan(1.0)*4;
 56 const int inf = 2139062143 / 2;
 57 
 58 class StrangeCountry
 59 {
 60     public:
 61         int f[100], cnt[100];
 62         int find (int x)
 63         {
 64             if (x != f[x]) f[x] = find(f[x]);
 65             return f[x];
 66         }
 67         int transform(vector <string> g){
 68             int num = 0;
 69             for (int i = 0; i < sz(g); ++ i)
 70                 for (int j = 0; j < sz(g); ++ j)
 71                     if (i != j && g[i][j] == 'Y') ++ num;
 72             num /= 2;
 73             if (num < sz(g)-1) return -1;
 74 
 75             for (int i = 0; i < sz(g); ++ i) f[i] = i;
 76             for (int i = 0; i < sz(g); ++ i)
 77                 for (int j = 0; j < sz(g); ++ j) if (g[i][j] == 'Y'){
 78                     int t1 = find(i), t2 = find(j);
 79                     if (t1 != t2) f[t1] = t2;
 80                 }
 81             int ret = 0;
 82             clr0 (cnt);
 83             for (int i = 0; i < sz(g); ++ i){
 84                 int t = find (i);
 85                 if (!cnt[t]) ++ ret;
 86                 ++ cnt[t];
 87             }
 88             for (int i = 0; i < sz(g); ++ i)
 89                 if (cnt[i] == 1) return -1;
 90             return ret - 1;
 91         }
 92         
 93 // BEGIN CUT HERE
 94     public:
 95     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(); }
 96     private:
 97     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(); }
 98     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; } }
 99     void test_case_0() { string Arr0[] = {"NYNNNNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYYNN", "YNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYYNN", "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNNNNN", "NNNNNNNNNNNNNYNNNNNNNNNNNNNNYNNNNNNNNNNNNNNN", "YNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYYNN", "NNNNNNNNNYNNNNNNNNNNNNNNNYYNNNNNNNNNNNNNNNNN", "NNNNNNNNYNNNYNNNNNNNNNNNNYNNNNNNNNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNYNNNNNNNNNNNNNNNNNNNNNNNNNY", "NNNNNNNNNNNNNYNNNNNNNYNNNNNNNNNNNNNNNNNNNNNN", "NNNNNNNNNYNNNNNNNNNNNNNNNYYNNNNNYNNNNNNNNNNN", "NNNNNNYNNNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNYNNNYNNNNNNNNNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNYNNNNNNNNNNNNNNNNYNNNNNNNNY", "NNNNNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNNNYNNNNNN", "NNNNNNNNNNYNNNNYNNNNNNNNNNNNNNNNNNYNNNNNNNNY", "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNYN", "NNNNNNNNNNNNNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", "NNNNNNNNNNNYNNNNNNNNNNNNNNNNNYNNNNNNYNYNNNNN", "NNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNNNNNNNNYNNYNNNNNNNNNNNNN", "NNNNNNNNNNNNNNYNYNNNNNNNNNNNNNNNNNNNNNNNNNNN", "NNNNYNNNYYNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", "NNNNNNNNYNNNYNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNNNNYNNNNNNYNNNNNNNNNNNNN", "NNNNNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", "NNNNNYNNNNNNNNNNNNNNNYNNNNNNNNNNNNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNNNNYNNNYNNNNNNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNYNNNNNNNNNNNNNNNNNNNNNNYN", "NNNNNNNNNNNNYNNNNNNNNNNNNNYNNNNNNNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNNNYNNNNNNNN", "NNNNNNNNNNNNNNNYNYNNNNNNNNNNNNNNNNNNNNNNNNNN", "NNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNNNNNNNYNNNNN", "NNNNNNNNNNNNNNNNYNNNNNNNNNNNNNNNNNNNNNNNNNNN", "NNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNNNNNYNNNNNNN", "YYNNNNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNN", "YYNNNNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYNYNN", "YYNNNNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNYYNNN", "NNNNNNNNNNNNNNNNNNNYNNNNNNNNNNNYNNNNNNNNNNNN", "NNNNNNNNNNYNNNNYNYNNNNNNNNNNNNNNNNNNNNNNNNNN"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 0; verify_case(0, Arg1, transform(Arg0)); }
100     void test_case_1() { string Arr0[] = {"NYYNN",
101  "YNYNN",
102  "YYNNN",
103  "NNNNY",
104  "NNNYN"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; verify_case(1, Arg1, transform(Arg0)); }
105     void test_case_2() { string Arr0[] = {"NYYNNNN",
106  "YNYNNNN",
107  "YYNNNNN",
108  "NNNNYYN",
109  "NNNYNYY",
110  "NNNYYNY",
111  "NNNNYYN"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; verify_case(2, Arg1, transform(Arg0)); }
112     void test_case_3() { string Arr0[] = {"NYNYNNNNNNNN",
113  "YNYNNNNNNNNN",
114  "NYNYYNNNNNNN",
115  "YNYNNNNNNNNN",
116  "NNYNNYYNNNNN",
117  "NNNNYNYNNNNN",
118  "NNNNYYNNNNNN",
119  "NNNNNNNNYYNN",
120  "NNNNNNNYNYNN",
121  "NNNNNNNYYNNN",
122  "NNNNNNNNNNNY",
123  "NNNNNNNNNNYN"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(3, Arg1, transform(Arg0)); }
124     void test_case_4() { string Arr0[] = {"NYNNNN",
125  "YNYNNN",
126  "NYNYNN",
127  "NNYNNN",
128  "NNNNNY",
129  "NNNNYN"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = -1; verify_case(4, Arg1, transform(Arg0)); }
130 
131 // END CUT HERE
132 
133 };
134 
135 // BEGIN CUT HERE
136 int main()
137 {
138 //    freopen( "a.out" , "w" , stdout );    
139     StrangeCountry ___test;
140     ___test.run_test(-1);
141        return 0;
142 }
143 // END CUT HERE
View Code

 

 

 

posted @ 2013-12-31 20:34  Plumrain  阅读(258)  评论(0编辑  收藏  举报