SRM144 - SRM 148(少144-DIV1-LV3,147-DIV2-LV3)
SRM 144
DIV 1 500pt
tag:组合
题意:彩票中奖。给定n, m,从1-n中选择m个数组成数列a1, a2, a3...am。对于数列{am}分别满足以下条件的概率:
(1)数列所有元素不相同且非严格递增;
(2)数列元素可以相同,可以递减;
(3)数列元素不相同,可以递减;
(4)数列元素可以相同,且非严格递增。
解法:所有四种情况均可以用排列组合公式直接解决,要用大数。最难的是最后一种情况,我也是最后一种情况公式写错了。
并且,最后一种情况公式的推导过程也可以看一看官方题解,是一种以前从来没用过的思考方法。
1 #include <cstdlib> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <vector> 8 #include <string> 9 #include <iostream> 10 #include <sstream> 11 #include <map> 12 #include <set> 13 #include <queue> 14 #include <stack> 15 #include <fstream> 16 #include <numeric> 17 #include <iomanip> 18 #include <bitset> 19 #include <list> 20 #include <stdexcept> 21 #include <functional> 22 #include <utility> 23 #include <ctime> 24 25 using namespace std; 26 27 #define CLR(x) memset(x, 0, sizeof(x)) 28 #define PB push_back 29 #define SZ(v) ((int)(v).size()) 30 #define rep(i, n) for(long long i = 0; i < (n); i ++) 31 #define repf(i, a, b) for(long long i = (a); i <= (b); i ++) 32 #define repd(i, a, b) for(long long i = (a); i >= (b); i --) 33 #define flin freopen( "a.in" , "r" , stdin ) 34 #define flout freopen( "a.out" , "w" , stdout ) 35 #define out(x) cout<<#x<<':'<<(x)<<endl 36 #define tst(a) cout<<#a<<endl 37 #define CINBEQUICKER std::ios::sync_with_stdio(false) 38 #define flag fla 39 40 typedef vector<int> VI; 41 typedef vector<string> VS; 42 typedef vector<double> VD; 43 typedef unsigned long long int64; 44 45 const double eps = 1e-8; 46 const double PI = atan(1.0)*4; 47 const int maxint = 2139062143; 48 49 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 50 51 class Node{ 52 public: 53 string name; 54 int64 num; 55 }node[100005]; 56 57 58 bool cmp( Node x , Node y ) 59 { 60 if( x.num < y.num ) 61 return true; 62 else if( x.num == y.num && x.name < y.name ) 63 return true; 64 return false; 65 } 66 67 int64 MyPow( int64 p , int64 n ) 68 { 69 int64 sq = 1; 70 while( n > 0 ){ 71 if( n % 2 ) 72 sq = sq * p; 73 n /= 2; 74 p = p * p; 75 } 76 return sq; 77 } 78 79 int64 C( int64 x , int64 y ) 80 { 81 int64 ans = 1; 82 for( int64 i = y , j = 1 ; i > y-x ; i-- , j ++ ) 83 ans = (ans*i) / j; 84 return ans; 85 } 86 87 int64 A( int64 x , int64 y ) 88 { 89 int64 ans = C(x,y); 90 repd( i , x , 1 ) 91 ans *= i; 92 return ans; 93 } 94 95 int64 Ask_Num( int a , int b , bool c , bool d ) 96 { 97 int64 ret; 98 if( c && d ) 99 ret = C(b,a); 100 if( c && !d ){ 101 //ret = MyPow(a,b) - C(b,a); /*Think : Why Wrong by this way?*/ 102 /*很好的组合问题,以下代码公式为C(b,a+b-1)Think why*/ 103 ret = 1; 104 for( int64 i = 0 ; i < b ; i ++ ) 105 ret *= ( a + b - i - 1 ); 106 for( int64 i = 0 ; i < b ; i ++ ) 107 ret /= ( i + 1 ); 108 /* end */ 109 } 110 if( !c && d ) 111 ret = A(b,a); 112 if( !c && !d ) 113 ret = MyPow(a,b); 114 return ret; 115 } 116 117 class Lottery 118 { 119 public: 120 vector <string> sortByOdds(vector <string> rules){ 121 int n = SZ( rules ); 122 rep( i , n ){ 123 node[i].name.clear(); 124 string s = rules[i]; 125 int len = SZ(s); 126 int flag; 127 rep( j , len ){ 128 if( s[j] == ':' ){ 129 flag = j; 130 break; 131 } 132 node[i].name.PB(s[j]); 133 } 134 flag += 2; 135 int a = ( s[flag] - '0' ) * 10 + s[flag+1] - '0'; 136 flag += 2; 137 if( s[flag] != ' ' ) 138 a = a * 10 + s[flag++] - '0'; 139 flag ++; 140 int b; 141 b = s[flag] - '0'; 142 flag += 2; 143 bool c = ( s[flag] == 'T' ); 144 flag += 2; 145 bool d = ( s[flag] == 'T' ); 146 node[i].num = Ask_Num( a , b , c , d ); 147 } 148 sort( node , node+n , cmp ); 149 VS anss; 150 anss.clear(); 151 rep( i , n ) 152 anss.PB( node[i].name ); 153 return (anss); 154 } 155 //by plum rain 156 };
DIV 1 1100pt
tag:没做,似乎图论
SRM 145
DIV 2 1100pt, DIV 1 600pt
tag: 模拟
1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 #line 7 "VendingMachine.cpp" 7 #include <cstdlib> 8 #include <cctype> 9 #include <cstring> 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 #include <vector> 14 #include <string> 15 #include <iostream> 16 #include <sstream> 17 #include <map> 18 #include <set> 19 #include <queue> 20 #include <stack> 21 #include <fstream> 22 #include <numeric> 23 #include <iomanip> 24 #include <bitset> 25 #include <list> 26 #include <stdexcept> 27 #include <functional> 28 #include <utility> 29 #include <ctime> 30 31 using namespace std; 32 33 #define CLR(x) memset(x, 0, sizeof(x)) 34 #define PB push_back 35 #define SZ(v) ((int)(v).size()) 36 #define rep(i, n) for(long long i = 0; i < (n); i ++) 37 #define repf(i, a, b) for(long long i = (a); i <= (b); i ++) 38 #define repd(i, a, b) for(long long i = (a); i >= (b); i --) 39 #define flin freopen( "a.in" , "r" , stdin ) 40 #define flout freopen( "a.out" , "w" , stdout ) 41 #define out(x) cout<<#x<<':'<<(x)<<endl 42 #define tst(a) cout<<#a<<endl 43 #define CINBEQUICKER std::ios::sync_with_stdio(false) 44 45 typedef vector<int> VI; 46 typedef vector<string> VS; 47 typedef vector<double> VD; 48 typedef long long int64; 49 50 const double eps = 1e-8; 51 const double PI = atan(1.0)*4; 52 const int maxint = 2139062143; 53 54 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 55 inline void swa(int &a, int &b) {int t = a;a = b;b = t;} 56 struct PUR{ 57 int c, s; 58 int time; 59 }bn[55]; 60 61 int an[55][55]; 62 int cn[55]; 63 int snum, cnum, pnum; 64 65 int rot(int a, int b) 66 { 67 if (a > b) 68 swa(a, b); 69 return min (b-a, cnum-b+a); 70 } 71 72 int find_max() 73 { 74 int tmp = 0, ret = 0; 75 rep (i, cnum) 76 if (tmp < cn[i]){ 77 tmp = cn[i]; 78 ret = i; 79 } 80 return ret; 81 } 82 83 int solve() 84 { 85 int ret = 0; 86 CLR(cn); 87 rep (i, cnum) 88 rep (j, snum) 89 cn[i] += an[j][i]; 90 int flag = find_max(); 91 ret += rot (0, flag); 92 rep (i, pnum){ 93 int s = bn[i].s, c = bn[i].c, tim = bn[i].time; 94 if (an[s][c] == 0) 95 return -1; 96 cn[c] -= an[s][c]; 97 an[s][c] = 0; 98 ret += rot (c, flag); 99 flag = c; 100 if (i < pnum-1 && bn[i+1].time - tim >= 5){ 101 int pos = flag; 102 flag = find_max(); 103 ret += rot (flag, pos); 104 } 105 } 106 int pos = flag; 107 flag = find_max(); 108 ret += rot (pos, flag); 109 return ret; 110 } 111 112 class VendingMachine 113 { 114 public: 115 int motorUse(vector <string> prices, vector <string> purchases){ 116 /*data initial*/ 117 CLR(an); 118 snum = SZ(prices); 119 int a = 0, pos = 0; 120 rep (i, snum){ 121 string s = prices[i]; 122 int size = SZ(s); 123 rep (j, size){ 124 if (s[j] == ' '){ 125 an[i][pos++] = a; 126 a = 0; 127 continue; 128 } 129 a = a * 10 + s[j] - '0'; 130 } 131 an[i][pos++] = a; 132 cnum = pos; 133 a = 0; 134 pos = 0; 135 } 136 cout << endl; 137 pnum = SZ(purchases); 138 rep (i, pnum){ 139 int a = 0; 140 string s = purchases[i]; 141 int j = 0; 142 while (s[j] != ','){ 143 a = a * 10 + s[j] - '0'; 144 j ++; 145 } 146 bn[i].s = a; 147 a = 0; j ++; 148 while (s[j] != ':'){ 149 a = a * 10 + s[j] - '0'; 150 j ++; 151 } 152 bn[i].c = a; 153 a = 0; j ++; 154 while (j < SZ(s)){ 155 a = a * 10 + s[j] - '0'; 156 j ++; 157 } 158 bn[i].time = a; 159 } 160 /*end initial*/ 161 return (solve()); 162 } 163 //by plum rain 164 };
DIV 1 1000pt
tag:dp
题意:爬山,从高度为0处爬高度为h的山,当前高度为k时,经过一步可以爬到k-1, k, k+1处。给定数字h, n, 数组{an},求满足以下条件的爬山方法种数:
(1)爬山过程中,必须到达过至少一次高度h处
(2)从高度0处开始爬山,并且最终回到高度0处,中途不能到高度0处
(3)总共走了n步
(4)如果将每一步到达的高度依次计入一个数组,比如从0爬到1再回到0计为数组{0, 1, 0},则{an}是它的一个子集。
解法:dp,比较普通,没什么好说的。感觉作为一道div1 lv3的题,并不难,只是情况比较复杂,我开了4维数组,写了两遍代码。
还是代码功底太弱了.....
1 #include <cstdlib> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <vector> 8 #include <string> 9 #include <iostream> 10 #include <sstream> 11 #include <map> 12 #include <set> 13 #include <queue> 14 #include <stack> 15 #include <fstream> 16 #include <numeric> 17 #include <iomanip> 18 #include <bitset> 19 #include <list> 20 #include <stdexcept> 21 #include <functional> 22 #include <utility> 23 #include <ctime> 24 25 using namespace std; 26 27 #define CLR(x) memset(x, 0, sizeof(x)) 28 #define PB push_back 29 #define SZ(v) ((int)(v).size()) 30 #define rep(i, n) for(int i = 0; i < (n); i ++) 31 #define repf(i, a, b) for(int i = (a); i <= (b); i ++) 32 #define repd(i, a, b) for(int i = (a); i >= (b); i --) 33 #define flin freopen( "a.in" , "r" , stdin ) 34 #define flout freopen( "a.out" , "w" , stdout ) 35 #define out(x) cout<<#x<<':'<<(x)<<endl 36 #define tst(a) cout<<#a<<endl 37 #define CINBEQUICKER std::ios::sync_with_stdio(false) 38 39 typedef vector<int> VI; 40 typedef vector<string> VS; 41 typedef vector<double> VD; 42 typedef long long int64; 43 44 const double eps = 1e-8; 45 const double PI = atan(1.0)*4; 46 const int maxint = 2139062143; 47 48 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 49 50 int d, m, n; 51 int64 dp[105][55][55][2]; 52 53 void DP(VI landmarks) 54 { 55 rep (i, d+1){ 56 rep (k, n+1) 57 rep (l, 2) 58 dp[i][0][k][l] = 0; 59 } 60 dp[0][0][0][0] = 1; 61 repf (i, 1, d){ 62 if (i == d){ 63 dp[i][0][n][1] = dp[i-1][1][n][1]; 64 break; 65 } 66 repf (j, 1, m){ 67 repf (k, 0, n){ 68 if (j < m){ 69 rep (l, 2){ 70 dp[i][j][k][l] = dp[i-1][j][k][l] + dp[i-1][j-1][k][l] + dp[i-1][j+1][k][l]; 71 if (k && j == landmarks[k-1]) 72 dp[i][j][k][l] = dp[i-1][j][k-1][l] + dp[i-1][j-1][k-1][l] + dp[i-1][j+1][k-1][l]; 73 } 74 } 75 else{ 76 dp[i][j][k][0] = 0; 77 dp[i][j][k][1] = dp[i-1][j][k][0] + dp[i-1][j-1][k][0] + dp[i-1][j][k][1] + dp[i-1][j-1][k][1]; 78 if (k && j == landmarks[k-1]) 79 dp[i][j][k][1] = dp[i-1][j][k-1][0] + dp[i-1][j-1][k-1][0] + dp[i-1][j][k-1][1] + dp[i-1][j-1][k-1][1]; 80 } 81 } 82 } 83 } 84 tst(aaa); 85 rep (i, d+1){ 86 out (i); 87 rep (j, m+1){ 88 rep (k, n+1) 89 cout << dp[i][j][k][0] << " " << dp[i][j][k][1] << " "; 90 cout << endl; 91 } 92 cout << endl << endl; 93 } 94 } 95 96 class HillHike 97 { 98 public: 99 long long numPaths(int distance, int maxHeight, vector <int> landmarks){ 100 d = distance; m = maxHeight; n = SZ(landmarks); 101 DP(landmarks); 102 return (dp[d][0][n][1]); 103 } 104 //by plum rain 105 };
SRM 146
DIV 1 300pt, DIV 2 500pt
tag:计数问题,math
1 #include <cstdlib> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <vector> 8 #include <iostream> 9 #include <sstream> 10 #include <set> 11 #include <queue> 12 #include <fstream> 13 #include <numeric> 14 #include <iomanip> 15 #include <bitset> 16 #include <list> 17 #include <stdexcept> 18 #include <functional> 19 #include <string> 20 #include <utility> 21 #include <map> 22 #include <ctime> 23 #include <stack> 24 25 using namespace std; 26 27 #define CLR(x) memset(x, 0, sizeof(x)) 28 #define PB push_back 29 #define SZ(v) ((int)(v).size()) 30 #define rep(i, n) for(int i = 0; i < (n); i ++) 31 #define repf(i, a, b) for(int i = (a); i <= (b); i ++) 32 #define repd(i, a, b) for(int i = (a); i >= (b); i --) 33 #define flin freopen( "a.in" , "r" , stdin ) 34 #define flout freopen( "a.out" , "w" , stdout ) 35 #define out(x) cout<<#x<<":"<<(x)<<endl 36 #define tst(a) cout<<#a<<endl 37 #define CINBEQUICKER std::ios::sync_with_stdio(false) 38 39 typedef vector<int> VI; 40 typedef vector<string> VS; 41 typedef vector<double> VD; 42 typedef long long int64; 43 44 const double eps = 1e-8; 45 const double PI = atan(1.0)*4; 46 const int maxint = 2139062143; 47 48 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 49 50 int64 ask_sqa(int64 n, int64 m) 51 { 52 int64 ret = 0; 53 int a = 1; 54 while (a <= m){ 55 ret += (n-a+1) * (m-a+1); 56 a ++; 57 } 58 return ret; 59 } 60 61 class RectangularGrid 62 { 63 public: 64 long long countRectangles(int width, int height){ 65 int64 n = width, m = height; 66 if (n < m) 67 swap (n, m); 68 int64 tot = ((n * (n + 1)) / 2) * m * (m + 1) / 2; 69 int64 sqa = ask_sqa(n, m); 70 return (tot - sqa); 71 } 72 73 };
DIV 1 600 pt
tag:dfs
1 #include <cstdlib> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <vector> 8 #include <iostream> 9 #include <sstream> 10 #include <set> 11 #include <queue> 12 #include <fstream> 13 #include <numeric> 14 #include <iomanip> 15 #include <bitset> 16 #include <list> 17 #include <stdexcept> 18 #include <functional> 19 #include <string> 20 #include <utility> 21 #include <map> 22 #include <ctime> 23 #include <stack> 24 25 using namespace std; 26 27 #define CLR(x) memset(x, true, sizeof(x)) 28 #define PB push_back 29 #define SZ(v) ((int)(v).size()) 30 #define rep(i, n) for(int i = 0; i < (n); i ++) 31 #define repf(i, a, b) for(int i = (a); i <= (b); i ++) 32 #define repd(i, a, b) for(int i = (a); i >= (b); i --) 33 #define flin freopen( "a.in" , "r" , stdin ) 34 #define flout freopen( "a.out" , "w" , stdout ) 35 #define out(x) cout<<#x<<":"<<(x)<<endl 36 #define tst(a) cout<<#a<<endl 37 #define CINBEQUICKER std::ios::sync_with_stdio(false) 38 39 typedef vector<int> VI; 40 typedef vector<string> VS; 41 typedef vector<double> VD; 42 typedef long long int64; 43 44 const double eps = 1e-8; 45 const double PI = atan(1.0)*4; 46 const int maxint = 2139062143; 47 const int maxx = 2401; 48 const int le = 1111; 49 const int ri = 7777; 50 51 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 52 53 struct po{ 54 bool hash[ri+1]; 55 }; 56 57 int n; 58 bool ans[ri+1]; 59 VS gg, rr; 60 61 bool can_apr(int num) 62 { 63 rep (i, 4){ 64 if (!((num%10) < 8) || !(num%10)) 65 return false; 66 num /= 10; 67 } 68 return true; 69 } 70 71 bool match (int num, int pos) 72 { 73 if (!can_apr(num)) 74 return false; 75 int b = 0, w = 0; 76 string g = gg[pos], r = rr[pos]; 77 int a[4]; 78 a[3] = num % 10; num = (num - a[3]) / 10; 79 a[2] = num % 10; num = (num - a[2]) / 10; 80 a[1] = num % 10; num = (num - a[1]) / 10; 81 a[0] = num % 10; 82 rep (i, 4){ 83 if (a[i]+'0' == g[i]){ 84 b ++; 85 a[i] = -1; 86 g[i] = 0; 87 } 88 } 89 rep (i, 4){ 90 rep (j, 4) 91 if (a[j]+'0' == g[i]){ 92 w ++; 93 a[j] = -1; 94 g[i] = 0; 95 break; 96 } 97 } 98 if (b+'0' != r[0] || w+'0' != r[3]) 99 return false; 100 return true; 101 } 102 103 void DFS(int pos, bool x, po p) 104 { 105 if (pos == n){ 106 if (x) 107 repf (i, le, ri) 108 ans[i] = (ans[i] || p.hash[i]); 109 return; 110 } 111 po tmp = p; 112 repf (i, le, ri){ 113 if (i == 1163 && pos == 1 && x){ 114 out (tmp.hash[1163]); 115 out (match (i, pos)); 116 } 117 if (tmp.hash[i] && !match (i, pos)) 118 tmp.hash[i] = false; 119 } 120 if (!pos) 121 out (tmp.hash[1163]); 122 if (pos == 1 && !x) 123 out (tmp.hash[1163]); 124 if (pos == 1 && x) 125 out (tmp.hash[1163]); 126 DFS(pos+1, x, tmp); 127 if (!x){ 128 tmp = p; 129 bool xxx[ri+1]; 130 CLR (xxx); 131 repf (i, le, ri){ 132 if (xxx[i] && !match (i, pos)) 133 xxx[i] = false; 134 } 135 repf (i, le, ri) 136 tmp.hash[i] = (tmp.hash[i] && !xxx[i]); 137 DFS (pos+1, 1, tmp); 138 } 139 } 140 141 class Masterbrain 142 { 143 public: 144 int possibleSecrets(vector <string> guesses, vector <string> results){ 145 n = SZ (guesses); 146 gg.clear(); rr.clear(); 147 gg = guesses; rr = results; 148 po p; 149 CLR (p.hash); 150 memset (ans, 0, sizeof(ans)); 151 DFS (0, 0, p); 152 int ret = 0; 153 repf (i, le, ri){ 154 if (can_apr(i) && ans[i]){ 155 ret ++; 156 cout << i << endl; 157 } 158 } 159 return (ret); 160 } 161 };
DIV 2 1000pt
tag:记忆划搜索
1 #include <cstdlib> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <vector> 8 #include <iostream> 9 #include <sstream> 10 #include <set> 11 #include <queue> 12 #include <fstream> 13 #include <numeric> 14 #include <iomanip> 15 #include <bitset> 16 #include <list> 17 #include <stdexcept> 18 #include <functional> 19 #include <string> 20 #include <utility> 21 #include <map> 22 #include <ctime> 23 #include <stack> 24 25 using namespace std; 26 27 #define CLR(x) memset(x, 0, sizeof(x)) 28 #define PB push_back 29 #define SZ(v) ((int)(v).size()) 30 #define rep(i, n) for(int i = 0; i < (n); i ++) 31 #define repf(i, a, b) for(int i = (a); i <= (b); i ++) 32 #define repd(i, a, b) for(int i = (a); i >= (b); i --) 33 #define flin freopen( "a.in" , "r" , stdin ) 34 #define flout freopen( "a.out" , "w" , stdout ) 35 #define out(x) cout<<#x<<":"<<(x)<<endl 36 #define tst(a) cout<<#a<<endl 37 #define CINBEQUICKER std::ios::sync_with_stdio(false) 38 39 typedef vector<int> VI; 40 typedef vector<string> VS; 41 typedef vector<double> VD; 42 typedef long long int64; 43 44 const double eps = 1e-8; 45 const double PI = atan(1.0)*4; 46 const int maxint = 2139062143; 47 const int N = 6; 48 49 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 50 51 int an[1<<N]; 52 int n; 53 VI t; 54 55 int Search (int now, int left) 56 { 57 if (left == 0){ 58 an[now] = 0; 59 return an[now]; 60 } 61 if (an[now]) 62 return an[now]; 63 int tmp = maxint; 64 rep (i, n){ 65 rep (j, n){ 66 if (i == j) 67 continue; 68 if ((now>>i) & 1 && (now>>j) & 1){ 69 if (left == 2){ 70 tmp = max (t[i], t[j]); 71 break; 72 } 73 now -= ((1<<i) + (1<<j)); 74 rep (k, n){ 75 if (!((now>>k) & 1)){ 76 now += (1<<k); 77 tmp = min (tmp, Search(now, left-1) + max (t[i], t[j]) + t[k]); 78 now -= (1<<k); 79 } 80 } 81 now += ((1<<i) + (1<<j)); 82 } 83 } 84 } 85 an[now] = tmp; 86 return an[now]; 87 } 88 class BridgeCrossing 89 { 90 public: 91 int minTime(vector <int> times){ 92 n = SZ (times); 93 if (n == 1) 94 return times[0]; 95 if (n == 2) 96 return max (times[0], times[1]); 97 t.clear(); 98 rep (i, n) 99 t.PB(times[i]); 100 sort (t.begin(), t.end()); 101 int ma = (1 << n) - 1; 102 CLR(an); 103 Search (ma, n); 104 return (Search(ma, n)); 105 } 106 };
DIV 1 800pt
tag: 模拟
Ps:800pt 的 lv3....
1 #include <cstdlib> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <vector> 8 #include <iostream> 9 #include <sstream> 10 #include <set> 11 #include <queue> 12 #include <fstream> 13 #include <numeric> 14 #include <iomanip> 15 #include <bitset> 16 #include <list> 17 #include <stdexcept> 18 #include <functional> 19 #include <string> 20 #include <utility> 21 #include <map> 22 #include <ctime> 23 #include <stack> 24 25 using namespace std; 26 27 #define CLR(x) memset(x, 0, sizeof(x)) 28 #define PB push_back 29 #define SZ(v) ((int)(v).size()) 30 #define rep(i, n) for(int i = 0; i < (n); i ++) 31 #define repf(i, a, b) for(int i = (a); i <= (b); i ++) 32 #define repd(i, a, b) for(int i = (a); i >= (b); i --) 33 #define flin freopen( "a.in" , "r" , stdin ) 34 #define flout freopen( "a.out" , "w" , stdout ) 35 #define out(x) cout<<#x<<":"<<(x)<<endl 36 #define tst(a) cout<<#a<<endl 37 #define CINBEQUICKER std::ios::sync_with_stdio(false) 38 39 typedef vector<int> VI; 40 typedef vector<string> VS; 41 typedef vector<double> VD; 42 typedef long long int64; 43 44 const double eps = 1e-8; 45 const double PI = atan(1.0)*4; 46 const int maxint = 2139062143; 47 48 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 49 50 char a[4]; 51 string s[4]; 52 bool stp[4]; 53 int tim = maxint; 54 55 bool match(int i, char x) 56 { 57 if (i == 0 && x == 'N') 58 return true; 59 if (i == 1 && x == 'E') 60 return true; 61 if (i == 2 && x == 'S') 62 return true; 63 if (i == 3 && x == 'W') 64 return true; 65 return false; 66 } 67 68 69 bool ok() 70 { 71 for (int i = 0; i < 4; i ++){ 72 if (a[i]) 73 return false; 74 if (!(SZ(s[i]) == 1 && s[i][0] == '-')) 75 return false; 76 } 77 return true; 78 } 79 80 81 void lesss(int x) 82 { 83 int len = SZ (s[x]); 84 for (int i = 0; i < len; i ++){ 85 if (s[x][i] == '-'){ 86 s[x].erase(i, 1); 87 break; 88 } 89 } 90 if (!SZ(s[x])) 91 s[x].PB ('-'); 92 } 93 94 void car_in() 95 { 96 for (int i = 0; i < 4; i ++){ 97 if (stp[i]) lesss(i); 98 else{ 99 if (s[i][0] == '-') lesss(i); 100 else{ 101 a[i] = s[i][0]; 102 s[i].erase(s[i].begin()); 103 if (!SZ (s[i])) 104 s[i].PB('-'); 105 } 106 } 107 108 } 109 } 110 111 void car_go() 112 { 113 for (int i = 0; i < 4; i ++) 114 if (match(i, a[i])) a[i] = 0; 115 char x = a[0]; 116 for (int i = 0; i < 3; i ++) 117 a[i] = a[i+1]; 118 a[3] = x; 119 } 120 121 bool stop(int x) 122 { 123 if (s[0][0] !='-' && s[1][0] != '-' && s[2][0] != '-' && s[3][0] != '-'){ 124 if (x) return true; 125 if (!a[1]) return false; 126 return true; 127 } 128 if (s[(x+1)%4][0] == '-' && !a[(x+1)%4]) 129 return false; 130 return true; 131 } 132 133 string clr(string x) 134 { 135 int len = SZ(x); 136 int flag = -1; 137 for (int i = 0; i < len; i ++){ 138 if (x[i] == '-') continue; 139 flag = i; 140 } 141 x.erase (flag+1, len-flag-1); 142 if (!SZ(x)) x.PB('-'); 143 return x; 144 } 145 146 class Roundabout 147 { 148 public: 149 int clearUpTime(string north, string east, string south, string west){ 150 tim = maxint; 151 CLR(a); 152 CLR(stp); 153 s[0].clear(); s[1].clear(); s[2].clear(); s[3].clear(); 154 s[0] = clr(north); 155 s[1] = clr(east); 156 s[2] = clr(south); 157 s[3] = clr(west); 158 for (int i = 0; i < 4; i ++ ) 159 if (stop (i)) stp[i] = 1; 160 tim = 0; 161 if (ok()) 162 return tim; 163 while (1){ 164 tim ++; 165 car_go(); 166 car_in(); 167 for (int i = 0; i < 4; i ++){ 168 if (stop(i)) stp[i] = 1; 169 else stp[i] = 0; 170 } 171 if (ok()) 172 break; 173 } 174 return (tim); 175 } 176 };
SRM 147
DIV 2 1000pt
tag:没做,看不懂题,让Jne帮忙看也没看懂
DIV 1 500pt
tag:模拟
Ps:代码写的太复杂了- -,up面和down面数目相同,front面和back面相同,left面和right面相同,则样代码就可以简化很多了- -。这就是没有仔细手算样例的后果- -
1 #include <cstdlib> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <vector> 8 #include <iostream> 9 #include <sstream> 10 #include <set> 11 #include <queue> 12 #include <fstream> 13 #include <numeric> 14 #include <iomanip> 15 #include <bitset> 16 #include <list> 17 #include <stdexcept> 18 #include <functional> 19 #include <string> 20 #include <utility> 21 #include <map> 22 #include <ctime> 23 #include <stack> 24 25 using namespace std; 26 27 #define CLR(x) memset(x, 0, sizeof(x)) 28 #define PB push_back 29 #define SZ(v) ((int)(v).size()) 30 #define out(x) cout<<#x<<":"<<(x)<<endl 31 #define tst(a) cout<<#a<<endl 32 #define CINBEQUICKER std::ios::sync_with_stdio(false) 33 34 typedef vector<int> VI; 35 typedef vector<string> VS; 36 typedef vector<double> VD; 37 typedef long long int64; 38 39 const double eps = 1e-8; 40 const double PI = atan(1.0)*4; 41 const int maxint = 2139062143; 42 43 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 44 45 struct fra{ 46 int64 a, b; 47 // a / b 48 void clr(){ 49 a = 0; b = 1; 50 } 51 }; 52 vector<fra> ans; 53 int r; 54 55 string ask(int64 x) 56 { 57 if (!x) 58 return "0"; 59 string s; 60 s.clear(); 61 while (x > 0){ 62 s.PB((x%10) + '0'); 63 x /= 10; 64 } 65 int size = SZ(s); 66 string ret; 67 ret.clear(); 68 for (int i = size-1; i >= 0; i --) 69 ret.PB(s[i]); 70 return ret; 71 } 72 73 string tostring() 74 { 75 string ret; 76 ret.clear(); 77 ret += ask (ans[2].a); 78 if (ans[2].b == 1) 79 return ret; 80 ret += '/'; 81 ret += ask (ans[2].b); 82 return ret; 83 } 84 85 int64 gcd(int64 a, int64 b){ 86 if (!b) return a; 87 return gcd (b, a%b); 88 } 89 90 fra Add(fra x, fra y){ 91 y.b *= 4; 92 if (x.b > y.b){ 93 fra t = x; 94 x = y; 95 y = t; 96 } 97 while (x.b < y.b){ 98 int64 g = gcd (x.b, y.b); 99 int64 mx = y.b / g, my = x.b / g; 100 x.a *= mx; x.b *= mx; 101 y.a *= my; y.b *= my; 102 } 103 fra ret; 104 ret.a = x.a + y.a; 105 ret.b = x.b; 106 while (!(ret.a % 2)){ 107 ret.a /= 2; 108 ret.b /= 2; 109 if (ret.b == 1) 110 break; 111 } 112 return ret; 113 } 114 115 VI match(int x){ 116 VI ret; 117 ret.clear(); 118 if (x == 0 || x == 1){ 119 for (int i = 2; i < 6; i ++) 120 ret.PB(i); 121 } 122 if (x == 2 || x == 3){ 123 ret.PB(0); ret.PB(1); 124 ret.PB(4); ret.PB(5); 125 } 126 if (x == 4 || x == 5){ 127 for (int i = 0; i < 4; i ++) 128 ret.PB(i); 129 } 130 return ret; 131 } 132 133 void change() 134 { 135 vector<fra> tmp; 136 tmp.clear(); 137 for (int i = 0; i < 6; i ++){ 138 VI x = match(i); 139 fra cnt; 140 cnt.clr(); 141 for (int j = 0; j < 4; j ++) 142 cnt = Add (cnt, ans[x[j]]); 143 tmp.PB(cnt); 144 } 145 ans.clear(); 146 ans = tmp; 147 } 148 149 class Dragons 150 { 151 public: 152 string snaug(vector <int> initialFood, int rounds){ 153 VI xx = initialFood; 154 if (xx[0] == xx[1] && xx[1] == xx[2] && xx[2] == xx[3] && xx[3] == xx[4] && xx[4] == xx[5]) 155 return ask(xx[2]); 156 r = rounds; 157 int64 size = SZ(xx); 158 fra x; 159 x.clr(); 160 ans.clear(); 161 for (int64 i = 0; i < size; i ++){ 162 x.a = xx[i]; 163 ans.PB(x); 164 } 165 int T = 0; 166 while (T < r){ 167 T ++; 168 change (); 169 } 170 string s = tostring(); 171 return (s); 172 } 173 //by plum rain 174 };
DIV 1 1000pt
tag:dp, good
题意:给定两个数字n(n <= 10),num(num <= 10^17),和vector<int> a[n],要求用n种颜色画出num面旗。
每面旗有x条竖条纹组成,条纹数不同的旗子一定不相同,条纹数相同但是对应条纹颜色不同的旗子也为不同的旗。
给条纹上色有一个条件,将n种颜色标为1~n,则如果a[i]中有数字k,则颜色i不能颜色k相邻(此时保证a[k]中一定有i)。
将所染旗帜中条纹数最多的旗帜的条纹数记为ans,求ans的最小值。
例如,n = 3,num = 10, a = {{0}, {1, 2}, {1, 2}},则染一条条纹的旗帜共有3种,染两条条纹的旗帜共有4种,染三条条纹的6种,3 + 4 + 6 = 13 >= 10,所以答案为3。
解法:首先肯定要用dp,而且dp部分很简单。难点在于,num可以达到10^17,意味着首先dp要注意空间复杂度优化,其次如果不特殊处理,肯定会超时。
考虑到,如果有任意一种颜色可以和两种颜色相邻,那么旗帜的条纹每增加一条所增加的染色种数是呈指数级增长的,ans也就很小,不会超时。
也就是说,只需要特判对每种颜色,能和它相邻的颜色都不超过1种的情况。
1 #include <cstdlib> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <vector> 8 #include <iostream> 9 #include <sstream> 10 #include <set> 11 #include <queue> 12 #include <fstream> 13 #include <numeric> 14 #include <iomanip> 15 #include <bitset> 16 #include <list> 17 #include <stdexcept> 18 #include <functional> 19 #include <string> 20 #include <utility> 21 #include <map> 22 #include <ctime> 23 #include <stack> 24 25 using namespace std; 26 27 #define CLR(x) memset(x, 0, sizeof(x)) 28 #define PB push_back 29 #define SZ(v) ((int)(v).size()) 30 #define out(x) cout<<#x<<":"<<(x)<<endl 31 #define tst(a) cout<<#a<<endl 32 #define CINBEQUICKER std::ios::sync_with_stdio(false) 33 34 typedef vector<int> VI; 35 typedef vector<string> VS; 36 typedef vector<double> VD; 37 typedef long long int64; 38 39 const double eps = 1e-8; 40 const double PI = atan(1.0)*4; 41 const int maxint = 2139062143; 42 43 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 44 45 bool fbd[15][15]; 46 int n; 47 int64 dp[2][10]; 48 int64 tot; 49 50 void init(string s) 51 { 52 tot = 0; 53 int pos = 0; 54 int size = SZ (s); 55 while (pos < size){ 56 tot = tot * 10 + s[pos++] - '0'; 57 } 58 } 59 60 int64 DP() 61 { 62 int64 ret; 63 int64 sum; 64 if (tot <= n) 65 return 1; 66 int spe = true; 67 int64 add = 0; 68 for (int i = 0; i < n; i ++){ 69 bool cnt = false; 70 for (int j = 0; j < n; j ++){ 71 if (fbd[i][j]) continue; 72 if (!cnt){ 73 cnt = true; 74 add ++; 75 continue; 76 } 77 spe = false; 78 break; 79 } 80 } 81 if (spe){ 82 ret = 1; 83 sum = n; 84 int64 tim = (tot - sum) / add; 85 if (n + tim * add >= tot) 86 return (tim + 1); 87 else return (tim + 2); 88 } 89 int pos = 0; 90 for (int i = 0; i < n; i ++) 91 dp[0][i] = 1; 92 ret = 1; 93 sum = n; 94 while (sum < tot){ 95 for (int i = 0; i < n; i ++){ 96 dp[(pos+1)%2][i] = 0; 97 for (int j = 0; j < n; j ++){ 98 if (fbd[i][j]) continue; 99 dp[(pos+1)%2][i] += dp[pos][j]; 100 } 101 sum += dp[(pos+1)%2][i]; 102 } 103 pos = (pos+1) % 2; 104 ret ++; 105 } 106 return ret; 107 } 108 109 class Flags 110 { 111 public: 112 long long numStripes(string numFlags, vector <string> forbidden){ 113 CLR(fbd); 114 init(numFlags); 115 n = SZ (forbidden); 116 for (int i = 0; i < n; i ++){ 117 string s = forbidden[i]; 118 int size = SZ (s); 119 for (int j = 0; j < size; j ++){ 120 if (s[j] == ' ') continue; 121 fbd[i][s[j]-'0'] = true; 122 } 123 } 124 int64 ans = DP(); 125 return (ans); 126 } 127 //by plum rain 128 };
SRM 148
DIV 1 1100pt
tag:recursion, good
题意:猜数字游戏,给定一个数字x,几个人分别猜测不同的数字,谁猜测数字与x之差最小谁赢,若有两人或多人与x之差相同且最小,则平手,平手不算赢!现在,题目给定数字n,m,数组{an}。
n表示猜数字范围为1~n,在你猜数字前已经有size(an)个人猜过数字,他们猜测的值记录在{an}中,在你猜之后,还将有m个人猜测。
不论你猜测哪个数字,在你之后猜测的人都采取最优策略(即使他自己赢的概率最大,如果猜两个数概率一样,猜小的),求猜多少能使你赢的概率最大。若有多个答案,输出最小的一个。
比如,n = 1000, {an} = {50}, m = 1。则答案为51, 因为当你猜51, 剩下的一个人为了使自己猜赢的概率最大,应该猜49或52,由于要猜小的,所以猜49,则你赢的概率为50,最优情况。
n <= 10^6,0 <= size(an) <= 10, 0 <= m <= 6, n ^ m <= 10^6。
解法:考虑递归。题目中的约束条件n ^ m <= 10^6可以起到提示的作用,但是如果直接暴力,时间复杂度为O(n^(m+1)),可能超时。考虑优化最后一个人猜测的情况。
在最后一个人猜测时情况为-----X--X--X-----X-----(---表示可猜测的点,X表示已猜测的点)
则,最后一个人可能猜测的点只有几个----OXO-XO-XO----XO----(最后一个人可能猜测的点为O),比较他们即可。
这样就用递归 + 枚举解决了问题。胆识程序很难写。因为对第m个人,他猜测的数字要影响第m+1个人,而m+1猜测的情况又会影响m。
我是参考了SnapDragon的代码。
1 #line 7 "NumberGuessing.cpp" 2 #include <cstdlib> 3 #include <cctype> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <vector> 9 #include <iostream> 10 #include <sstream> 11 #include <set> 12 #include <queue> 13 #include <fstream> 14 #include <numeric> 15 #include <iomanip> 16 #include <bitset> 17 #include <list> 18 #include <stdexcept> 19 #include <functional> 20 #include <string> 21 #include <utility> 22 #include <map> 23 #include <ctime> 24 #include <stack> 25 26 using namespace std; 27 28 #define CLR(x) memset(x, 0, sizeof(x)) 29 #define PB push_back 30 #define SZ(v) ((int)(v).size()) 31 #define out(x) cout<<#x<<":"<<(x)<<endl 32 #define tst(a) cout<<#a<<endl 33 #define CINBEQUICKER std::ios::sync_with_stdio(false) 34 35 typedef vector<int> VI; 36 typedef vector<string> VS; 37 typedef vector<double> VD; 38 typedef long long int64; 39 40 const double eps = 1e-8; 41 const double PI = atan(1.0)*4; 42 const int maxint = 2139062143; 43 const int N = 1000005; 44 45 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 46 47 int n; 48 int num[30], pnum; 49 int tot; 50 51 void xequal(int an[], bool x) 52 { 53 if (x){ 54 for (int i = 0; i < tot; ++ i) 55 an[i] = num[i]; 56 return ; 57 } 58 for (int i = 0; i < tot; ++ i) 59 num[i] = an[i]; 60 } 61 62 int cal (int x, bool xxx) 63 { 64 int t[30], tnum = tot; 65 xequal (t, 1); 66 if (xxx) tnum --; 67 sort (t, t+tnum); 68 if (tnum == -1) return n; 69 if (x < t[0]) 70 return x + ((t[0] - x - 1) >> 1); 71 if (x == t[0]) 72 return x + ((t[1] - x - 1) >> 1); 73 int flag = 0; //添加flag是为了不用特判x 与 t[i]会重合的情况 74 for (int i = 0; i < tnum; ++ i){ 75 if (x == t[i]) flag = 1; 76 if (x < t[i]) 77 return 1 + ((t[i] - x - 1) >> 1) + ((x - t[i-1-flag] - 1) >> 1); 78 } 79 return n - x + 1 + ((x - t[tnum-1-flag]) >> 1); 80 } 81 82 int findpos() 83 { 84 int t[30], tnum = tot - 1; 85 xequal (t, 1); 86 sort (t, t+tnum); 87 int ret, pret = 0; 88 if (tnum == 0) return 1; 89 if (t[0] > 1) 90 ret = t[0] - 1, pret = cal (t[0]-1, 1); 91 for (int i = 0; i < tnum; ++ i){ 92 if (t[i] >= n) continue; 93 if (i < tnum-1 && t[i] + 1 == t[i+1]) 94 continue; 95 int tmp = cal (t[i]+1, 1); 96 if (tmp > pret) 97 ret = t[i] + 1, pret = tmp; 98 } 99 return ret; 100 } 101 102 int DFS(int pos, int c) 103 { 104 pnum = pos + tot - c - 1; 105 if (pos == c){ 106 int tmp = findpos(); 107 num[pnum] = tmp; 108 return tmp; 109 } 110 int ntmp[30], ret, pret = 0; 111 xequal(ntmp, 1); 112 for (int i = 1; i <= n; ++ i){ 113 bool xxx = true; 114 for (int j = 0; j < pnum; ++ j) 115 if (num[j] == i){ 116 xxx = false; 117 break; 118 } 119 if (!xxx) continue; 120 pnum = pos + tot - c - 1; 121 num[pnum] = i; 122 DFS(pos+1, c); 123 pnum = pos + tot - c - 1; 124 int ptmp = cal (i, 0); 125 if (ptmp > pret) 126 pret = ptmp, ret = i, xequal (ntmp, 1); 127 } 128 xequal (ntmp, 0); 129 return ret; 130 } 131 132 class NumberGuessing 133 { 134 public: 135 int bestGuess(int A, vector <int> B, int c){ 136 int size = SZ (B); 137 n = A, tot = size + c + 1; 138 CLR (num), pnum = -1; 139 for (int i = 0; i < size; ++ i) 140 num[++pnum] = B[i]; 141 return DFS(0, c); 142 } 143 //by plum rain 144 };
小结:受了别人的推荐,尝试做了一点topcoder的题,现在看了,这些题确实是很有价值的。
并且,这几天对自己做题时存在的两个问题感觉特别明显。
一是代码功底太差了。div2 lv3, div1 lv2,div1 lv3这三道题的代码都不小,每次我写完以后都要调试很久才能和自己的想的算法吻合。而且,上面有不少题的代码都是重写过的,因为之前写的错误太多,修改太麻烦,而且容易引出新的错误。
二是自己写前总是没有或者很难对自己要写的代码有一个比较准确的估计。比如有时把问题想简单了,有时又忽略了个别限制条件,写到一半或者写完了调试的时候才发现,然后又去改。这个时候更改,不仅浪费时间,而且很容易造成新的错误。
刷题!
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。