SRM 358(1-250,500pt)
DIV1 250pt
题意:电视目前停留在第100台,有一个遥控器,可以向上或向下换台(需要按键一次),也可以按一些数字,然后直接跳到该台(需要按键次数等于数字数,不需要按确定键)。但是,这个遥控一些数字键是坏的不能按。问要换到x台最少需要按多少次。x <= 500000。
解法:直接搜索。可能用bfs会快点,但我更喜欢写dfs就用了。
tag:search
1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 #line 7 "BrokenButtons.cpp" 7 #include <cstdlib> 8 #include <cctype> 9 #include <cstring> 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 #include <vector> 14 #include <iostream> 15 #include <sstream> 16 #include <set> 17 #include <queue> 18 #include <fstream> 19 #include <numeric> 20 #include <iomanip> 21 #include <bitset> 22 #include <list> 23 #include <stdexcept> 24 #include <functional> 25 #include <string> 26 #include <utility> 27 #include <map> 28 #include <ctime> 29 #include <stack> 30 31 using namespace std; 32 33 #define clr0(x) memset(x, 0, sizeof(x)) 34 #define clr1(x) memset(x, -1, sizeof(x)) 35 #define pb push_back 36 #define mp make_pair 37 #define sz(v) ((int)(v).size()) 38 #define out(x) cout<<#x<<":"<<(x)<<endl 39 #define tst(x) cout<<x<<":"<<" " 40 #define tst1(a) cout<<#a<<endl 41 #define CINBEQUICKER std::ios::sync_with_stdio(false) 42 43 typedef vector<int> vi; 44 typedef vector<string> vs; 45 typedef vector<double> vd; 46 typedef long long int64; 47 48 const double eps = 1e-8; 49 const double PI = atan(1.0)*4; 50 const int inf = 2139062143 / 2; 51 52 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 53 54 class BrokenButtons 55 { 56 public: 57 int ans, len, p; 58 bool v[20]; 59 void dfs(int x, int num) 60 { 61 if (num) ans = min(ans, abs(p-x) + num); 62 if (num <= len) 63 for (int i = 0; i < 10; ++ i) if (!v[i]) dfs (x*10+i, num+1); 64 } 65 int minPresses(int pag, vector <int> bro){ 66 clr0 (v); 67 for (int i = 0; i < sz(bro); ++ i) v[bro[i]] = 1; 68 ans = abs(pag-100); p = pag; len = 0; 69 while (pag) pag /= 10, len ++; 70 dfs (0, 0); 71 return ans; 72 } 73 74 // BEGIN CUT HERE 75 public: 76 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(); } 77 private: 78 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(); } 79 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; } } 80 void test_case_0() { int Arg0 = 5457; int Arr1[] = { 6, 7, 8 }; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 6; verify_case(0, Arg2, minPresses(Arg0, Arg1)); } 81 void test_case_1() { int Arg0 = 100; int Arr1[] = { 1, 0, 5 }; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 0; verify_case(1, Arg2, minPresses(Arg0, Arg1)); } 82 void test_case_2() { int Arg0 = 14124; int Arr1[] = { }; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 5; verify_case(2, Arg2, minPresses(Arg0, Arg1)); } 83 void test_case_3() { int Arg0 = 1; int Arr1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 2; verify_case(3, Arg2, minPresses(Arg0, Arg1)); } 84 void test_case_4() { int Arg0 = 80000; int Arr1[] = { 8, 9 }; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 2228; verify_case(4, Arg2, minPresses(Arg0, Arg1)); } 85 86 // END CUT HERE 87 88 }; 89 //by plum rain 90 // BEGIN CUT HERE 91 int main() 92 { 93 //freopen( "a.out" , "w" , stdout ); 94 BrokenButtons ___test; 95 ___test.run_test(-1); 96 return 0; 97 } 98 // END CUT HERE
DIV1 500pt
题意:有一个数字a[],a的某子数组b[]如果能表示出a,则称b为好子数组。能表示出的意思即为,可以写出如下等式:对任意a[i]均有,a[i] = b[0]*t0 + b[1]*t1 + b[2]*t2 + b[3]*t3 + ... + b[m-1]*t(m-1).(b中有m个元素)。给定a,求它的元素数量最少的好子数组b。
a[i] <= 10^7
解法:首先,从a中选出一些元素形成所求的b,其余元素构成数组b'。则一定有,b中所有元素的最大公约数一定是b'中所有元素的最大公约数的约数,否则无法表示。
所以,为了方便,先将a中所有元素都除以最大公约数,然后在其中找到最少个数,使得找出的数最大公约数为1即可。
其次,注意到,a[i]中每个元素含有质因子的个数最多为8个。(2*3*...23>10^7)
所以,由于b中至少含有一个元素,所以对所有a[i],枚举a[i]在b中的时候,b中最少含有多少个数,问题可以由集合dp得到解决。
tag:math, dp, good
1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 #line 7 "BalanceScale.cpp" 7 #include <cstdlib> 8 #include <cctype> 9 #include <cstring> 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 #include <vector> 14 #include <iostream> 15 #include <sstream> 16 #include <set> 17 #include <queue> 18 #include <fstream> 19 #include <numeric> 20 #include <iomanip> 21 #include <bitset> 22 #include <list> 23 #include <stdexcept> 24 #include <functional> 25 #include <string> 26 #include <utility> 27 #include <map> 28 #include <ctime> 29 #include <stack> 30 31 using namespace std; 32 33 #define clr(x) memset(x, 0, sizeof(x)) 34 #define clrs(x,y) memset(x, y, sizeof(x)) 35 #define pb push_back 36 #define sz(v) ((int)(v).size()) 37 #define all(v) (v).begin(), (v).end() 38 #define out(x) cout<<#x<<":"<<(x)<<endl 39 #define tst(x) cout<<x<<" " 40 #define tst1(a) cout<<#a<<endl 41 #define CINBEQUICKER std::ios::sync_with_stdio(false) 42 43 typedef long long int64; 44 typedef vector<int> vi; 45 typedef vector<string> vs; 46 typedef vector<double> vd; 47 typedef pair<int, int> pii; 48 49 const double eps = 1e-8; 50 const double PI = atan(1.0)*4; 51 const int inf = 2139062143 / 2; 52 53 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 54 55 int d[55][1<<9]; 56 vi divv; 57 58 class BalanceScale 59 { 60 public: 61 int gao(int sta, int x) 62 { 63 int m = sz(divv), ret = 0; 64 for (int i = 0; i < m; ++ i) if (sta & (1<<i)){ 65 if (x % divv[i] == 0) ret |= 1 << i; 66 } 67 return ret; 68 } 69 int takeWeights(vector <int> w){ 70 sort(all(w)); 71 int gd = w[0], n = sz(w); 72 for (int i = 1; i < n; ++ i) gd = __gcd(gd, w[i]); 73 for (int i = 0; i < n; ++ i){ 74 w[i] /= gd; 75 if (w[i] == 1) return 1; 76 } 77 int ans = n; 78 for (int i = 0; i < n; ++ i){ 79 int tmp = w[i]; 80 divv.clear(); 81 for (int64 j = 2; j*j <= tmp; ++ j) if (tmp % j == 0){ 82 divv.pb (j); 83 while (tmp % j == 0) tmp /= j; 84 } 85 if (tmp != 1) divv.pb (tmp); 86 87 int m = sz(divv); 88 clr (d); d[0][(1<<m)-1] = 1; 89 for (int j = 0; j < n; ++ j){ 90 for (int k = 0; k <= j; ++ k) 91 for (int t = 0; t < (1<<m); ++ t) 92 if (d[k][t]) d[k+1][gao(t, w[j])] = 1; 93 } 94 95 for (int j = 1; j < n; ++ j) if (d[j][0]) ans = min(ans, j+1); 96 } 97 return ans; 98 } 99 100 // BEGIN CUT HERE 101 public: 102 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(); } 103 private: 104 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(); } 105 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; } } 106 //void test_case_0() { int Arr0[] = { 5, 4, 1, 8 }; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; verify_case(0, Arg1, takeWeights(Arg0)); } 107 void test_case_0() { int Arr0[] = {3828825, 2159850, 4594590, 22, 1939392}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; verify_case(0, Arg1, takeWeights(Arg0)); } 108 void test_case_1() { int Arr0[] = { 2, 3, 8, 9 }; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(1, Arg1, takeWeights(Arg0)); } 109 void test_case_2() { int Arr0[] = { 60, 105, 490, 42 }; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 4; verify_case(2, Arg1, takeWeights(Arg0)); } 110 void test_case_3() { int Arr0[] = { 15, 25, 9 }; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(3, Arg1, takeWeights(Arg0)); } 111 112 // END CUT HERE 113 114 }; 115 //by plum rain 116 // BEGIN CUT HERE 117 int main() 118 { 119 //freopen( "a.out" , "w" , stdout ); 120 BalanceScale ___test; 121 ___test.run_test(-1); 122 return 0; 123 } 124 // END CUT HERE
------------------------------------------------------------------
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。