zoukankan      html  css  js  c++  java
  • 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 << "	Expected: " << print_array(Expected) << endl; cerr << "	Received: " << 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
    View Code

    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 << "	Expected: " << print_array(Expected) << endl; cerr << "	Received: " << 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
    View Code
  • 相关阅读:
    工作中遇到的令人头疼的bug
    Cookie的简单用法
    C#之#if #endif的简单用法
    我们一起学习WCF 第十篇Wcf中实现事务
    一次性搞定Session
    设计模式-观察者模式
    类的扩展之 DataReader的扩展
    C#之Ref,Out以及TryParse()的用法
    C#之Lambda不得不说的用法
    C#之Action和Func的用法
  • 原文地址:https://www.cnblogs.com/plumrain/p/SRM_404.html
Copyright © 2011-2022 走看看