TC SRM 589
这套题不难……但看错题是硬伤……因为这个蛋疼的原因花了三天时间才搞定……
250pt:
现在做250pt的题感觉也比以前做起来水了,看来在HZC的指导下还是有所长进的。
题意是给一个字符串,每次可以把某种字符全部变成另一种字符,代价为这种字符的数量,使用最少的代价变成回文串。
由于同种字符是任意时刻都是一样的,所以用并查集维护当前哪几种字符是一样的,再维护一个当前字符的cnt,每次贪心选就行了。
1 #include <vector>
2 #include <list>
3 #include <map>
4 #include <set>
5 #include <queue>
6 #include <deque>
7 #include <stack>
8 #include <bitset>
9 #include <algorithm>
10 #include <functional>
11 #include <numeric>
12 #include <utility>
13 #include <sstream>
14 #include <iostream>
15 #include <iomanip>
16 #include <cstdio>
17 #include <cmath>
18 #include <cstdlib>
19 #include <ctime>
20
21 using namespace std;
22
23 int f[200],cnt[200];
24
25 int getf(int x)
26 {
27 if (f[x]==x) return x;
28 else return f[x]=getf(f[x]);
29 }
30
31
32 class GooseTattarrattatDiv1 {
33 public:
34 int getmin(string S) {
35 int n=S.size();
36 for (int a='a';a<='z';a++)
37 f[a]=a,cnt[a]=0;
38 for (int a=0;a<n;a++)
39 cnt[S[a]]++;
40 int ans=0;
41 for (int a=0,b=n-1;a<b;a++,b--)
42 {
43 int c1=S[a];
44 int c2=S[b];
45 int f1=getf(c1);
46 int f2=getf(c2);
47 if (f1!=f2)
48 {
49 if (cnt[f1]<cnt[f2]) swap(f1,f2);
50 ans+=cnt[f2];
51 f[f2]=f1;
52 }
53 }
54 return ans;
55 }
56 };
57
58
59 //<%:testing-code%>
60 //Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!
61 // BEGIN KAWIGIEDIT TESTING
62 // Generated by KawigiEdit 2.1.4 (beta) modified by pivanof
63 bool KawigiEdit_RunTest(int testNum, string p0, bool hasAnswer, int p1) {
64 cout << "Test " << testNum << ": [" << "\"" << p0 << "\"";
65 cout << "]" << endl;
66 GooseTattarrattatDiv1 *obj;
67 int answer;
68 obj = new GooseTattarrattatDiv1();
69 clock_t startTime = clock();
70 answer = obj->getmin(p0);
71 clock_t endTime = clock();
72 delete obj;
73 bool res;
74 res = true;
75 cout << "Time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
76 if (hasAnswer) {
77 cout << "Desired answer:" << endl;
78 cout << "\t" << p1 << endl;
79 }
80 cout << "Your answer:" << endl;
81 cout << "\t" << answer << endl;
82 if (hasAnswer) {
83 res = answer == p1;
84 }
85 if (!res) {
86 cout << "DOESN'T MATCH!!!!" << endl;
87 } else if (double(endTime - startTime) / CLOCKS_PER_SEC >= 2) {
88 cout << "FAIL the timeout" << endl;
89 res = false;
90 } else if (hasAnswer) {
91 cout << "Match :-)" << endl;
92 } else {
93 cout << "OK, but is it right?" << endl;
94 }
95 cout << "" << endl;
96 return res;
97 }
98 int main() {
99 bool all_right;
100 all_right = true;
101
102 string p0;
103 int p1;
104
105 {
106 // ----- test 0 -----
107 p0 = "geese";
108 p1 = 2;
109 all_right = KawigiEdit_RunTest(0, p0, true, p1) && all_right;
110 // ------------------
111 }
112
113 {
114 // ----- test 1 -----
115 p0 = "tattarrattat";
116 p1 = 0;
117 all_right = KawigiEdit_RunTest(1, p0, true, p1) && all_right;
118 // ------------------
119 }
120
121 {
122 // ----- test 2 -----
123 p0 = "xyyzzzxxx";
124 p1 = 2;
125 all_right = KawigiEdit_RunTest(2, p0, true, p1) && all_right;
126 // ------------------
127 }
128
129 {
130 // ----- test 3 -----
131 p0 = "xrepayuyubctwtykrauccnquqfuqvccuaakylwlcjuyhyammag";
132 p1 = 11;
133 all_right = KawigiEdit_RunTest(3, p0, true, p1) && all_right;
134 // ------------------
135 }
136
137 {
138 // ----- test 4 -----
139 p0 = "abaabb";
140 p1 = 3;
141 all_right = KawigiEdit_RunTest(4, p0, true, p1) && all_right;
142 // ------------------
143 }
144
145 if (all_right) {
146 cout << "You're a stud (at least on the example cases)!" << endl;
147 } else {
148 cout << "Some of the test cases had errors." << endl;
149 }
150 return 0;
151 }
152 // END KAWIGIEDIT TESTING
450pt:
三种颜色的齿轮,告诉你互相之间的连接情况,要求同种颜色的齿轮必须转向相同,问最少要移走多少个齿轮。
HZC说这题很自然就能想出解法,可我完全想不出来。
枚举齿轮转向,然后相同转向的齿轮如果相连那么必然要移除一个,那么如果两个齿轮转向相同且相连就连条边,问题转化为了最大独立集的问题。然后发现三种齿轮同向的情况可以不考虑之后发现图是个二分图所以直接可以用匹配解掉了。
1 #include <vector>
2 #include <list>
3 #include <map>
4 #include <set>
5 #include <queue>
6 #include <deque>
7 #include <stack>
8 #include <bitset>
9 #include <algorithm>
10 #include <functional>
11 #include <numeric>
12 #include <utility>
13 #include <sstream>
14 #include <iostream>
15 #include <iomanip>
16 #include <cstdio>
17 #include <cmath>
18 #include <cstdlib>
19 #include <ctime>
20 #include <cstring>
21
22 using namespace std;
23
24 int n,col[100],id[100],en,result[100];
25
26 bool c[100][100],use[100];
27
28 struct edge
29 {
30 int e;
31 edge *next;
32 }*v[100],ed[10000];
33
34 void add_edge(int s,int e)
35 {
36 en++;
37 ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
38 }
39
40 bool dfs(int now)
41 {
42 for (edge *e=v[now];e;e=e->next)
43 if (!use[e->e])
44 {
45 use[e->e]=true;
46 if (!result[e->e] || dfs(result[e->e]))
47 {
48 result[e->e]=now;
49 return true;
50 }
51 }
52 return false;
53 }
54
55 int solve(int c1,int c2)
56 {
57 int cnt1=0,cnt2=0;
58 for (int a=0;a<n;a++)
59 if (col[a]==c1) id[a]=++cnt1;
60 else
61 {
62 if (col[a]==c2) id[a]=++cnt2;
63 }
64 en=0;
65 memset(v,0,sizeof(v));
66 for (int a=0;a<n;a++)
67 for (int b=0;b<n;b++)
68 if (col[a]==c1 && col[b]==c2 && c[a][b]) add_edge(id[a],id[b]);
69 int ans=0;
70 memset(result,0,sizeof(result));
71 for (int a=1;a<=cnt1;a++)
72 {
73 memset(use,false,sizeof(use));
74 if (dfs(a)) ans++;
75 }
76 return ans;
77 }
78
79 class GearsDiv1 {
80 public:
81 int getmin(string color, vector <string> graph) {
82 n=color.size();
83 for (int a=0;a<n;a++)
84 if (color[a]=='R') col[a]=0;
85 else
86 {
87 if (color[a]=='G') col[a]=1;
88 else col[a]=2;
89 }
90 for (int a=0;a<n;a++)
91 for (int b=0;b<n;b++)
92 if (graph[a][b]=='Y') c[a][b]=true;
93 else c[a][b]=false;
94 return min(solve(0,1),min(solve(1,2),solve(0,2)));
95 }
96 };
97
98
99 //<%:testing-code%>
100 //Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!
101 // BEGIN KAWIGIEDIT TESTING
102 // Generated by KawigiEdit 2.1.4 (beta) modified by pivanof
103 bool KawigiEdit_RunTest(int testNum, string p0, vector <string> p1, bool hasAnswer, int p2) {
104 cout << "Test " << testNum << ": [" << "\"" << p0 << "\"" << "," << "{";
105 for (int i = 0; int(p1.size()) > i; ++i) {
106 if (i > 0) {
107 cout << ",";
108 }
109 cout << "\"" << p1[i] << "\"";
110 }
111 cout << "}";
112 cout << "]" << endl;
113 GearsDiv1 *obj;
114 int answer;
115 obj = new GearsDiv1();
116 clock_t startTime = clock();
117 answer = obj->getmin(p0, p1);
118 clock_t endTime = clock();
119 delete obj;
120 bool res;
121 res = true;
122 cout << "Time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
123 if (hasAnswer) {
124 cout << "Desired answer:" << endl;
125 cout << "\t" << p2 << endl;
126 }
127 cout << "Your answer:" << endl;
128 cout << "\t" << answer << endl;
129 if (hasAnswer) {
130 res = answer == p2;
131 }
132 if (!res) {
133 cout << "DOESN'T MATCH!!!!" << endl;
134 } else if (double(endTime - startTime) / CLOCKS_PER_SEC >= 2) {
135 cout << "FAIL the timeout" << endl;
136 res = false;
137 } else if (hasAnswer) {
138 cout << "Match :-)" << endl;
139 } else {
140 cout << "OK, but is it right?" << endl;
141 }
142 cout << "" << endl;
143 return res;
144 }
145 int main() {
146 bool all_right;
147 all_right = true;
148
149 string p0;
150 vector <string> p1;
151 int p2;
152
153 {
154 // ----- test 0 -----
155 p0 = "RGB";
156 string t1[] = {"NYY","YNY","YYN"};
157 p1.assign(t1, t1 + sizeof(t1) / sizeof(t1[0]));
158 p2 = 1;
159 all_right = KawigiEdit_RunTest(0, p0, p1, true, p2) && all_right;
160 // ------------------
161 }
162
163 {
164 // ----- test 1 -----
165 p0 = "RGBR";
166 string t1[] = {"NNNN","NNNN","NNNN","NNNN"};
167 p1.assign(t1, t1 + sizeof(t1) / sizeof(t1[0]));
168 p2 = 0;
169 all_right = KawigiEdit_RunTest(1, p0, p1, true, p2) && all_right;
170 // ------------------
171 }
172
173 {
174 // ----- test 2 -----
175 p0 = "RGBR";
176 string t1[] = {"NYNN","YNYN","NYNY","NNYN"};
177 p1.assign(t1, t1 + sizeof(t1) / sizeof(t1[0]));
178 p2 = 1;
179 all_right = KawigiEdit_RunTest(2, p0, p1, true, p2) && all_right;
180 // ------------------
181 }
182
183 {
184 // ----- test 3 -----
185 p0 = "RRRRRGRRBGRRGBBGGGBRRRGBRGRRGG";
186 string t1[] = {"NNNNNYNNNYNNYNNNYNNNNNNNNYNNYY","NNNNNNNNYNNNYNYNNYNNNNYNNYNNYY","NNNNNYNNNNNNNNNNNNYNNNNNNYNNNY","NNNNNNNNNYNNYNNYYYNNNNYNNYNNNN","NNNNNNNNNYNNYNNYYYNNNNYNNNNNNN","YNYNNNYYYNNYNYYNNNNNYYNYNNYYNN","NNNNNYNNNNNNNNNYYYNNNNYNNYNNYY","NNNNNYNNNNNNNNNYNNNNNNNNNNNNYN","NYNNNYNNNYNNYNNYYYNNNNYNNYNNYY","YNNYYNNNYNNNNYYNNNYNYYNYNNNNNN","NNNNNNNNNNNNYNNYNYNNNNYNNNNNNY","NNNNNYNNNNNNYNNYYYNNNNNNNNNNYN","YYNYYNNNYNYYNYYNNNYNYNNYNNNNNN","NNNNNYNNNYNNYNNYYYNNNNYNNYNYYY","NYNNNYNNNYNNYNNYYYNNNNYNNYNNYY","NNNYYNYYYNYYNYYNNNYNYNNYYNYYNN","YNNYYNYNYNNYNYYNNNYNNNNYYNNYNN","NYNYYNYNYNYYNYYNNNNYYNNYYNYNNN","NNYNNNNNNYNNYNNYYNNNNNYNNYNNNY","NNNNNNNNNNNNNNNNNYNNNNYNNYNNNY","NNNNNYNNNYNNYNNYNYNNNNYNNNNNYY","NNNNNYNNNYNNNNNNNNNNNNYNNNNNNN","NYNYYNYNYNYNNYYNNNYYYYNYYNYNNN","NNNNNYNNNYNNYNNYYYNNNNYNNNNNNY","NNNNNNNNNNNNNNNYYYNNNNYNNYNNYY","YYYYNNYNYNNNNYYNNNYYNNNNYNYYNN","NNNNNYNNNNNNNNNYNYNNNNYNNYNNYN","NNNNNYNNNNNNNYNYYNNNNNNNNYNNYY","YYNNNNYYYNNYNYYNNNNNYNNNYNYYNN","YYYNNNYNYNYNNYYNNNYYYNNYYNNYNN"};
187 p1.assign(t1, t1 + sizeof(t1) / sizeof(t1[0]));
188 p2 = 3;
189 all_right = KawigiEdit_RunTest(3, p0, p1, true, p2) && all_right;
190 // ------------------
191 }
192
193 if (all_right) {
194 cout << "You're a stud (at least on the example cases)!" << endl;
195 } else {
196 cout << "Some of the test cases had errors." << endl;
197 }
198 return 0;
199 }
200 // END KAWIGIEDIT TESTING
900pt:
给一个长度不超过250的二进制数(一开始看成50觉得太水了后来又看成2500发现完全不会了最后才发现是250……),两种代价均为1的操作:1、将任意一位取反。2、将前k*M位全部取反,问最小代价使得前L-M位和后L-M位相同。
首先用K表示第二种操作有多少种是可行的,显而易见这K种操作每种最多做一次,所以K比较小时就直接2^K枚举检验即可。对于K比较大M比较小的时候,整个二进制数的1-M位、M+1-2M位……这些应该都是相等的。所以直接2^M枚举前M位是什么样的,然后向后做一次DP得出结果。
1 #include <vector>
2 #include <list>
3 #include <map>
4 #include <set>
5 #include <queue>
6 #include <deque>
7 #include <stack>
8 #include <bitset>
9 #include <algorithm>
10 #include <functional>
11 #include <numeric>
12 #include <utility>
13 #include <sstream>
14 #include <iostream>
15 #include <iomanip>
16 #include <cstdio>
17 #include <cmath>
18 #include <cstdlib>
19 #include <ctime>
20 #include <cstring>
21
22 using namespace std;
23
24 int f[1000][2];
25
26 bool rev[1000],z[1000];
27
28 class FlippingBitsDiv1 {
29 public:
30 int getmin(vector <string> S, int M) {
31 string s;
32 int n=S.size();
33 for (int a=0;a<n;a++)
34 s=s+S[a];
35 n=s.size();
36 int k=n/M;
37 int ans=n+k+1;
38 if (k<=16)
39 {
40 for (int a=0;a<(1<<k);a++)
41 {
42 memset(rev,false,sizeof(rev));
43 int cnt=0;
44 for (int b=0;b<k;b++)
45 if ((a>>b)&1) rev[min(b*M+M-1,n-1)]=true,cnt++;
46 for (int b=0;b<n;b++)
47 z[b]=s[b]-'0';
48 bool now=false;
49 for (int b=n-1;b>=0;b--)
50 {
51 now^=rev[b];
52 z[b]^=now;
53 }
54 for (int b=0;b<M;b++)
55 {
56 int cnt1=0,cnt2=0;
57 for (int c=b;c<n;c+=M)
58 if (z[c]) cnt1++;
59 else cnt2++;
60 cnt+=min(cnt1,cnt2);
61 }
62 ans=min(ans,cnt);
63 }
64 }
65 else
66 {
67 for (int b=0;b<n;b++)
68 z[b]=s[b]-'0';
69 int x;
70 for (int a=0;a<(1<<M);a++)
71 {
72 for (int b=0,c=1;b<n;b+=M,c++)
73 {
74 f[c][0]=f[c][1]=n+k+1;
75 for (int d=0;d<2;d++)
76 {
77 int cnt1=0,cnt2=0;
78 for (int e=b;e<b+M && e<n;e++)
79 if (z[e]!=(z[e%M]^d^(((a>>(e-b))&1)))) cnt1++;
80 else cnt2++;
81 f[c][d]=min(f[c][d],f[c-1][d]+cnt1);
82 f[c][d^1]=min(f[c][d^1],f[c-1][d]+cnt2+1);
83 }
84 x=c;
85 }
86 ans=min(ans,min(f[x][0],f[x][1]));
87 }
88 }
89 return ans;
90 }
91 };
92
93
94 //<%:testing-code%>
95 //Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!
96 // BEGIN KAWIGIEDIT TESTING
97 // Generated by KawigiEdit 2.1.4 (beta) modified by pivanof
98 bool KawigiEdit_RunTest(int testNum, vector <string> p0, int p1, bool hasAnswer, int p2) {
99 cout << "Test " << testNum << ": [" << "{";
100 for (int i = 0; int(p0.size()) > i; ++i) {
101 if (i > 0) {
102 cout << ",";
103 }
104 cout << "\"" << p0[i] << "\"";
105 }
106 cout << "}" << "," << p1;
107 cout << "]" << endl;
108 FlippingBitsDiv1 *obj;
109 int answer;
110 obj = new FlippingBitsDiv1();
111 clock_t startTime = clock();
112 answer = obj->getmin(p0, p1);
113 clock_t endTime = clock();
114 delete obj;
115 bool res;
116 res = true;
117 cout << "Time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
118 if (hasAnswer) {
119 cout << "Desired answer:" << endl;
120 cout << "\t" << p2 << endl;
121 }
122 cout << "Your answer:" << endl;
123 cout << "\t" << answer << endl;
124 if (hasAnswer) {
125 res = answer == p2;
126 }
127 if (!res) {
128 cout << "DOESN'T MATCH!!!!" << endl;
129 } else if (double(endTime - startTime) / CLOCKS_PER_SEC >= 2) {
130 cout << "FAIL the timeout" << endl;
131 res = false;
132 } else if (hasAnswer) {
133 cout << "Match :-)" << endl;
134 } else {
135 cout << "OK, but is it right?" << endl;
136 }
137 cout << "" << endl;
138 return res;
139 }
140 int main() {
141 bool all_right;
142 all_right = true;
143
144 vector <string> p0;
145 int p1;
146 int p2;
147
148 {
149 // ----- test 0 -----
150 string t0[] = {"00111000"};
151 p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
152 p1 = 1;
153 p2 = 2;
154 all_right = KawigiEdit_RunTest(0, p0, p1, true, p2) && all_right;
155 // ------------------
156 }
157
158 {
159 // ----- test 1 -----
160 string t0[] = {"101100001101"};
161 p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
162 p1 = 3;
163 p2 = 2;
164 all_right = KawigiEdit_RunTest(1, p0, p1, true, p2) && all_right;
165 // ------------------
166 }
167
168 {
169 // ----- test 2 -----
170 string t0[] = {"11111111"};
171 p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
172 p1 = 4;
173 p2 = 0;
174 all_right = KawigiEdit_RunTest(2, p0, p1, true, p2) && all_right;
175 // ------------------
176 }
177
178 {
179 // ----- test 3 -----
180 string t0[] = {"1101001000"};
181 p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
182 p1 = 8;
183 p2 = 1;
184 all_right = KawigiEdit_RunTest(3, p0, p1, true, p2) && all_right;
185 // ------------------
186 }
187
188 {
189 // ----- test 4 -----
190 string t0[] = {"1","10","11","100","101","110"};
191 p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
192 p1 = 5;
193 p2 = 4;
194 all_right = KawigiEdit_RunTest(4, p0, p1, true, p2) && all_right;
195 // ------------------
196 }
197
198 {
199 // ----- test 5 -----
200 string t0[] = {"1001011000101010001111111110111011011100110001001"};
201 p0.assign(t0, t0 + sizeof(t0) / sizeof(t0[0]));
202 p1 = 2;
203 p2 = 16;
204 all_right = KawigiEdit_RunTest(5, p0, p1, true, p2) && all_right;
205 // ------------------
206 }
207
208 if (all_right) {
209 cout << "You're a stud (at least on the example cases)!" << endl;
210 } else {
211 cout << "Some of the test cases had errors." << endl;
212 }
213 return 0;
214 }
215 // END KAWIGIEDIT TESTING