SRM 404(1-250pt, 1-500pt)
DIV1 250pt
题意:对于1-9数字三角形如下图,设其为a[i][j],则a[i][j] = (a[i-1][j] + a[i-1][j+1]) % 10。现在对于某个数字三角形, 每行告诉你某一个位置的数字,求整个数字三角形。
n <= 50。
解法:首先,由于最后一行和倒数第二行共3个数,已知2个,所以就能求出剩下一个,然后一个往上,一行一行将每个数求出来。时间复杂度小于O(10*n^2)。
tag:think
1 // BEGIN CUT HERE 2 /* 3 * Author: plum rain 4 * score : 5 */ 6 /* 7 8 */ 9 // END CUT HERE 10 #line 11 "RevealTriangle.cpp" 11 #include <sstream> 12 #include <stdexcept> 13 #include <functional> 14 #include <iomanip> 15 #include <numeric> 16 #include <fstream> 17 #include <cctype> 18 #include <iostream> 19 #include <cstdio> 20 #include <vector> 21 #include <cstring> 22 #include <cmath> 23 #include <algorithm> 24 #include <cstdlib> 25 #include <set> 26 #include <queue> 27 #include <bitset> 28 #include <list> 29 #include <string> 30 #include <utility> 31 #include <map> 32 #include <ctime> 33 #include <stack> 34 35 using namespace std; 36 37 #define CLR(x) memset(x, 0, sizeof(x)) 38 #define CLR1(x) memset(x, -1, sizeof(x)) 39 #define PB push_back 40 #define SZ(v) ((int)(v).size()) 41 #define ALL(t) t.begin(),t.end() 42 #define zero(x) (((x)>0?(x):-(x))<eps) 43 #define out(x) cout<<#x<<":"<<(x)<<endl 44 #define tst(a) cout<<#a<<endl 45 #define CINBEQUICKER std::ios::sync_with_stdio(false) 46 47 typedef vector<int> VI; 48 typedef vector<string> VS; 49 typedef vector<double> VD; 50 typedef pair<int, int> pii; 51 typedef long long int64; 52 53 const double eps = 1e-8; 54 const double PI = atan(1.0)*4; 55 const int maxint = 2139062143; 56 57 class RevealTriangle 58 { 59 public: 60 vector <string> calcTriangle(vector <string> q){ 61 int sz = q.size(); 62 string s; 63 for (int i = sz-2; i >= 0; -- i){ 64 s = q[i]; 65 int pos = 0; 66 for (int j = 0; j < s.size(); ++ j) 67 if (s[j] >= '0' && s[j] <= '9'){ 68 pos = j; break; 69 } 70 71 for (int k = pos-1; k >= 0; -- k) 72 for (int t = 0; t < 10; ++ t) 73 if ((t+s[k+1]-'0') % 10 == q[i+1][k] - '0') 74 s[k] = t + '0'; 75 for (int k = pos+1; k < s.size(); ++ k) 76 for (int t = 0; t < 10; ++ t) 77 if ((t+s[k-1]-'0') % 10 == q[i+1][k-1] - '0') 78 s[k] = t + '0'; 79 80 q[i] = s; 81 } 82 return q; 83 } 84 85 // BEGIN CUT HERE 86 public: 87 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(); } 88 private: 89 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(); } 90 void verify_case(int Case, const vector <string> &Expected, const vector <string> &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; } } 91 void test_case_0() { string Arr0[] = {"4??", 92 "?2", 93 "1"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = {"457", "92", "1" }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(0, Arg1, calcTriangle(Arg0)); } 94 void test_case_1() { string Arr0[] = {"1"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = {"1" }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(1, Arg1, calcTriangle(Arg0)); } 95 void test_case_2() { string Arr0[] = {"???2", "??2", "?2", "2"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = {"0002", "002", "02", "2" }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(2, Arg1, calcTriangle(Arg0)); } 96 void test_case_3() { string Arr0[] = {"??5?", "??9", "?4", "6"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = {"7054", "759", "24", "6" }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(3, Arg1, calcTriangle(Arg0)); } 97 98 // END CUT HERE 99 100 }; 101 102 // BEGIN CUT HERE 103 int main() 104 { 105 // freopen( "a.out" , "w" , stdout ); 106 RevealTriangle ___test; 107 ___test.run_test(-1); 108 return 0; 109 } 110 // END CUT HERE
DIV1 500pt
题意:通过O(n)的方法生成一个长度为n的数列a[]。定义s(i,k) = a[i] + a[i+1] + ... + a[i+k-1]。求最小的|s(i,k) - s(j,k)|,其中i+k-1 < j,并返回k和|s(i,k) - s(j,k)|。如果有多组解,返回k值较大的。
解法:枚举k,求出k固定时最小的满足题意的i, j, k。下面考虑k已经固定的情况。
法一:维护一个set,然后用二分查找绝对值差最小的一组。这样的方法时间复杂度O(n*n*logn),但是常数很大,不一定能过。
法二:考虑一个结论,对于任意一组i, j, k,如果i+k-1 >= j,则一定存在另一组i', j', k'满足i' + k' - 1 < j',且|s(i, k) - s(j, k)| = |s(i', k') - s(j', k')|。
所以得到的方法是,首先记录答案返回值为k_idx 和 val,对于所有的s(i, j)做一排序,第一影响因素是s(i, j)从小到大,第二影响因素是i从小到大,将排序结果存在num[]中。对于num[]中的相邻元素t1和t2(t1在t2之前),有两种可能:
1、如果t1和t2的s(i, k)之差不为0,则if(|t1.s - t2.s| <= val && |t1.i - t2.i| >= k) 更新答案val和k_idx,否则不更新。
2、如果t1和t2的s(i, k)相等,则考虑找出所有s(i, k)与他们相同的项,然后取i之差最大的两项来比较。当然,这个要提前预处理好,不然会很慢。具体见代码。
tag:think, good
1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 #line 7 "KSubstring.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 PB push_back 35 #define SZ(v) ((int)(v).size()) 36 #define ALL(x) (x).begin(), (x).end() 37 #define out(x) cout<<#x<<":"<<(x)<<endl 38 #define tst(a) cout<<#a<<endl 39 #define CINBEQUICKER std::ios::sync_with_stdio(false) 40 41 typedef vector<int> VI; 42 typedef vector<string> VS; 43 typedef vector<double> VD; 44 typedef long long int64; 45 46 const double eps = 1e-8; 47 const double PI = atan(1.0)*4; 48 const int maxint = 2139062143; 49 50 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 51 52 struct nod{ 53 int64 num, s; 54 }; 55 56 int64 a[5000]; 57 nod num[5000]; 58 int pos[5000]; 59 60 bool cmp(nod a, nod b) 61 { 62 return b.num < a.num || (a.num == b.num && a.s < b.s); 63 } 64 65 class KSubstring 66 { 67 public: 68 vector <int> maxSubstring(int a0, int x, int y, int mod, int n){ 69 a[0] = a0; 70 for (int i = 1; i < n; ++ i) a[i] = (a[i-1]*x + y) % mod; 71 72 int64 val = 1LL<<62; 73 int k_idx = 0; 74 for (int k = 1; k <= n/2; ++ k){ 75 int64 sum = 0, idx = 0; 76 for (int i = 0; i < k; ++ i) sum += a[i]; 77 for (int i = 0; i+k <= n; ++ i){ 78 num[idx].num = sum; 79 num[idx++].s = i; 80 sum = sum - a[i] + a[i+k]; 81 } 82 83 sort(num, num+idx, cmp); 84 int p = idx-1; 85 int64 tnum = num[idx-1].num; 86 for (int i = idx-1; i >= 0; -- i){ 87 if (num[i].num != tnum){ 88 pos[i] = i+1; p = i; tnum = num[i].num; 89 } 90 else pos[i] = p; 91 } 92 for (int i = 0; i < idx; ++ i){ 93 int64 tmp = abs(num[i].num - num[pos[i]].num); 94 int64 pdif = abs(num[pos[i]].s - num[i].s); 95 if (pdif >= k && val >= tmp){ 96 k_idx = k; val = tmp; 97 } 98 } 99 } 100 VI ans; ans.PB (k_idx); ans.PB ((int)val); 101 return ans; 102 } 103 104 // BEGIN CUT HERE 105 public: 106 //void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_2();} 107 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(); } 108 private: 109 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(); } 110 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; } } 111 void test_case_0() { int Arg0 = 5; int Arg1 = 3; int Arg2 = 4; int Arg3 = 25; int Arg4 = 5; int Arr5[] = {2, 1 }; vector <int> Arg5(Arr5, Arr5 + (sizeof(Arr5) / sizeof(Arr5[0]))); verify_case(0, Arg5, maxSubstring(Arg0, Arg1, Arg2, Arg3, Arg4)); } 112 void test_case_1() { int Arg0 = 8; int Arg1 = 19; int Arg2 = 17; int Arg3 = 2093; int Arg4 = 12; int Arr5[] = {5, 161 }; vector <int> Arg5(Arr5, Arr5 + (sizeof(Arr5) / sizeof(Arr5[0]))); verify_case(1, Arg5, maxSubstring(Arg0, Arg1, Arg2, Arg3, Arg4)); } 113 void test_case_2() { int Arg0 = 53; int Arg1 = 13; int Arg2 = 9; int Arg3 = 65535; int Arg4 = 500; int Arr5[] = {244, 0 }; vector <int> Arg5(Arr5, Arr5 + (sizeof(Arr5) / sizeof(Arr5[0]))); verify_case(2, Arg5, maxSubstring(Arg0, Arg1, Arg2, Arg3, Arg4)); } 114 void test_case_3() { int Arg0 = 12; int Arg1 = 34; int Arg2 = 55; int Arg3 = 7890; int Arg4 = 123; int Arr5[] = {35, 4 }; vector <int> Arg5(Arr5, Arr5 + (sizeof(Arr5) / sizeof(Arr5[0]))); verify_case(3, Arg5, maxSubstring(Arg0, Arg1, Arg2, Arg3, Arg4)); } 115 116 // END CUT HERE 117 118 }; 119 //by plum rain 120 // BEGIN CUT HERE 121 int main() 122 { 123 //freopen( "a.out" , "w" , stdout ); 124 KSubstring ___test; 125 ___test.run_test(-1); 126 return 0; 127 } 128 // END CUT HERE
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。