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 << "	" << p1 << endl;
 79     }
 80     cout << "Your answer:" << endl;
 81     cout << "	" << 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
View Code

 

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 << "	" << p2 << endl;
126     }
127     cout << "Your answer:" << endl;
128     cout << "	" << 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
View Code

 

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 << "	" << p2 << endl;
121     }
122     cout << "Your answer:" << endl;
123     cout << "	" << 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
View Code

 

原文地址:https://www.cnblogs.com/zhonghaoxi/p/3290237.html