250pt : 模拟题
#include <cstdio> #include <cstring> #include <cctype> #include <cstdlib> #include <cmath> #include <ctime> #include <iostream> #include <map> #include <set> #include <list> #include <sstream> #include <queue> #include <deque> #include <stack> #include <vector> #include <bitset> #include <algorithm> using namespace std; #define clr(a, x) memset(a, x, sizeof(a)) #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define REP(i,a,b) for(int i=a;i<=b;i++) template <class T> void checkmax(T &t, T x) { if (x > t) t = x; } template <class T> void checkmin(T &t, T x) { if (x < t) t = x; } template <class T> void _checkmax(T &t, T x) { if (t == -1 || x > t) t = x; } template <class T> void _checkmin(T &t, T x) { if (t == -1 || x < t) t = x; } #define pb push_back class PermutationSignature { public: vector <int> reconstruct(string signature) ; // BEGIN CUT HERE public: 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(); } private: 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(); } void verify_case(int Case, const vector <int> &Expected, const vector <int> &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: " << print_array(Expected) << endl; cerr << "\tReceived: " << print_array(Received) << endl; } } void test_case_0() { string Arg0 = "IIIII"; int Arr1[] = {1, 2, 3, 4, 5, 6 }; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(0, Arg1, reconstruct(Arg0)); } void test_case_1() { string Arg0 = "DI"; int Arr1[] = {2, 1, 3 }; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(1, Arg1, reconstruct(Arg0)); } void test_case_2() { string Arg0 = "IIIID"; int Arr1[] = {1, 2, 3, 4, 6, 5 }; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(2, Arg1, reconstruct(Arg0)); } void test_case_3() { string Arg0 = "DIIDID"; int Arr1[] = {2, 1, 3, 5, 4, 7, 6 }; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(3, Arg1, reconstruct(Arg0)); } // END CUT HERE }; vector <int> PermutationSignature::reconstruct(string signature) { string s = signature; vector <int> ans; int i, j, k; for(i = 0;i < s.size(); i++) if(s[i] == 'D') { int j = i; while(s[j] == 'D') j++; for(k = j;k > i; k--) ans.pb(k+1); ans.pb(i+1); i = j; } else { int j = i; while(s[j] == 'I') j++; for(k = i;k < j; k++) ans.pb(k+1); i = j-1; } if(ans.size() != s.size()+1) ans.pb(s.size()+1); return ans; } // BEGIN CUT HERE int main() { PermutationSignature ___test; ___test.run_test(-1); return 0; } // END CUT HERE
550pt :题意很难弄懂,给你一个森林,每个节点都有一个tag和一个颜色,有两个操作,第一个给某一个节点涂上某种颜色,第二个操作给某一个节点的所有的子树的所有的节点属性为指点tag的节点涂上某一个颜色,问最少需要多少次操作使得所有的节点都为相应的颜色。给节点涂颜色会覆盖原来的颜色
这样的话就是树形DP的解法了,和一般的树形DP不同的是这个题目DP是由父节点传到子节点
dp[i][j][k][l]表示对i节点为根的子树进行染色,其中当前3种tag的节点颜色已经为j k l的时候最少需要染多少次,dp转移就是枚举对这个节点的子孙的3种tag分别进行哪种染色操作,dp复杂度80*8^6
#include <cstdio> #include <cstring> #include <cctype> #include <cstdlib> #include <cmath> #include <ctime> #include <iostream> #include <map> #include <set> #include <list> #include <sstream> #include <queue> #include <deque> #include <stack> #include <vector> #include <bitset> #include <algorithm> using namespace std; #define clr(a, x) memset(a, x, sizeof(a)) #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define REP(i,a,b) for(int i=a;i<=b;i++) template <class T> void checkmax(T &t, T x) { if (x > t) t = x; } template <class T> void checkmin(T &t, T x) { if (x < t) t = x; } template <class T> void _checkmax(T &t, T x) { if (t == -1 || x > t) t = x; } template <class T> void _checkmin(T &t, T x) { if (t == -1 || x < t) t = x; } class CssRules { public: int getMinimalCssRuleCount(vector <string> xthml); // BEGIN CUT HERE public: 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(); } private: 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(); } 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; } } void test_case_0() { string Arr0[] = {"<b id='x' style='color:red'></b>"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; verify_case(0, Arg1, getMinimalCssRuleCount(Arg0)); } void test_case_1() { string Arr0[] = {"<b id='x' style='color:red'>","<b id='y' style='color:red'>", "<b id='z' style='color:red'>","</b></b></b>"} ; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(1, Arg1, getMinimalCssRuleCount(Arg0)); } void test_case_2() { string Arr0[] = {"<b id='x' style='color:red'>", "<b id='y' style='color:red'>", "<b id='w' style='color:red'>", "</b>", "</b>", "<u id='z' style='color:red'>", "</u>", "</b>"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 3; verify_case(2, Arg1, getMinimalCssRuleCount(Arg0)); } void test_case_3() { string Arr0[] = {"<b id='x' style='color:red'>", "<i id='y' style='color:black'>", "<u id='w' style='color:white'>", "</u>", "</i>", "<u id='z' style='color:yellow'>", "</u>", "</b>"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 4; verify_case(3, Arg1, getMinimalCssRuleCount(Arg0)); } void test_case_4() { string Arr0[] = {"<b id='x' style='col", "or:red'></b>", "<b id=", "'xx' style='color", ":red'></b>"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(4, Arg1, getMinimalCssRuleCount(Arg0)); } // END CUT HERE }; string color[9] = { "black", "blue", "gray", "green", "red", "white", "yellow" }; struct PP { int t,next ; }node[22222]; struct MES { int color, tag; }mes[111]; int dp[111][8][8][8], head[111], root[111], num, E; void newnode(int u,int v) { node[E].t = v; node[E].next = head[u]; head[u] = E++; } int get_tag(char b) { if(b == 'b') return 0; if(b == 'u') return 1; if(b == 'i') return 2; return -1; } int get_color(string s) { for(int i = 0;i < 7; i++) if(s == color[i]) return i+1; return -1; } int min(int a,int b) { return a < b ? a : b; } int dfs(int cur,int t0,int t1,int t2) { if(dp[cur][t0][t1][t2] != -1) return dp[cur][t0][t1][t2]; int add = 0; if(mes[cur].tag == 0) add += mes[cur].color != t0; if(mes[cur].tag == 1) add += mes[cur].color != t1; if(mes[cur].tag == 2) add += mes[cur].color != t2; if(head[cur] == -1) { return dp[cur][t0][t1][t2] = add; } int i, j, k, l, ans = 111111111; for(i = 0;i < 8; i++) { for(j = 0;j < 8; j++) { for(k = 0;k < 8; k++) { int sum = add; if(i != t0) sum++; if(j != t1) sum++; if(k != t2) sum++; for(l = head[cur];l != -1; l = node[l].next) { sum += dfs(node[l].t,i,j,k); } ans = min(ans, sum); } } } dp[cur][t0][t1][t2] = ans; return dp[cur][t0][t1][t2] = ans; } void DFS(int u) { for(int i = head[u];i != -1;i = node[i].next) { printf("%d %d\n", u,node[i].t); DFS(node[i].t); } } int CssRules::getMinimalCssRuleCount (vector <string> xthml) { string s; num = E = 0; memset(dp, -1, sizeof(dp)); memset(head, -1, sizeof(head)); stack<int> q; int i, j, k; for(i = 0;i < xthml.size(); i++) { s = s + xthml[i]; } int tot = 0; for(i = 0;i < s.size(); i++) if(s[i] == '<') { if(s[i+1] != '/') { int tag = get_tag(s[i+1]); for(j = i;j < s.size(); j++) if(s[j] == ':') break; j++; string ss; while(s[j] != '\'') ss += s[j++]; int color = get_color(ss); mes[num].color = color; mes[num].tag = tag; if(q.size() != 0) { int pre = q.top(); newnode(pre,num); } else { root[tot++] = num; } q.push(num); num++; i = j+1; } else { q.pop(); } } int ans = 0; for(i = 0;i < tot; i++) { ans += dfs(root[i],0,0,0); } printf("ans = %d\n", ans); return ans; } // BEGIN CUT HERE int main() { CssRules ___test; ___test.run_test(-1); return 0; } // END CUT HERE