• 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第六章 1(Lists)


    127 - "Accordian" Patience

    题目大意:一个人一张张发牌,如果这张牌与这张牌前面的一张或者前面的第三张(后面称之为一位置和三位置)的点数或花式相同,则将这张牌移动到与之对应的位置(优先三位置,也就是说如果一位置与三位置都有以上的性质则移动到三位置之上),移动之后若仍以上的性质,则继续操作,直到已发的所有牌都无法移动之后再继续发牌,(如果一个位置被移空,则删除此位置!)

    解题思路:用数组模拟链表,每发一张牌就匹配三位置,如果匹配就移动,否则再看一位置是否满足,如果满足就移动,移动之后,再继续之前的操作,直到所有的都不能移动!如果都不满足,则继续发牌!如此反复直到所有牌都发完!最后只剩下几叠移不动的牌,依次输出每叠的数量。最开始的数是总叠数,如果是1则输出“1 pile remaining: ”其他则输出“6 piles remaining: ”!

    解题代码:

      1 //Author:   Freetion
      2 //file:        127 - "Accordian" Patience
      3 
      4 #include <iostream>
      5 #include <math.h>
      6 #include <string.h>
      7 #include <stdio.h>
      8 using namespace std;
      9 
     10 struct node
     11 {
     12     string pile[53];
     13     int num;
     14 }pat[53];
     15 bool noth[53];
     16 
     17 int main()
     18 {
     19     freopen("data.in", "r", stdin);
     20     freopen("data.out", "w", stdout);
     21     string tm;
     22     while (cin >> tm && tm[0] != '#')
     23     {
     24         memset (noth, false, sizeof (noth));
     25         int i = 0;
     26         pat[i].pile[0] = "";
     27         pat[i].pile[0] += tm;
     28         pat[i++].num = 1;
     29         for ( ; i < 52; i ++)
     30         {
     31             pat[i].num = 0;
     32             cin >> pat[i].pile[pat[i].num++]; 
     33         }
     34 /*        for (i = 0; i < 52; i ++)
     35             cout << pat[i].pile[0] << " ";
     36         for (i = 0; i < 52; i ++)
     37             cout << pat[i].num << " ";
     38 */
     39         int total = 52;
     40         for (i = 0; i < 52; i ++)
     41         {
     42             int bf = 0, cm = i - 1;
     43             while (bf < 3 && cm >= 0)
     44             {
     45                 if (noth[cm --])
     46                     continue;
     47                 bf ++;
     48             }
     49             if (bf == 3 && !noth[i])
     50             {
     51                 node& cmp_1 = pat[i];
     52                 node& cmp_2 = pat[cm+1];
     53                 if ( cmp_1.pile[cmp_1.num-1][0] == cmp_2.pile[cmp_2.num-1][0] )
     54                 {
     55                     cmp_2.pile[cmp_2.num] = "";
     56                     cmp_2.pile[cmp_2.num ++] += cmp_1.pile[--cmp_1.num];
     57                     if (cmp_1.num <= 0)
     58                     {
     59                         noth[i] = true;
     60                         total --;
     61                     }
     62                     i = cm;
     63                     continue;
     64                 }
     65                 else if ( cmp_1.pile[cmp_1.num-1][1] == cmp_2.pile[cmp_2.num-1][1] )
     66                 {
     67                     cmp_2.pile[cmp_2.num] = "";
     68                     cmp_2.pile[cmp_2.num ++] += cmp_1.pile[--cmp_1.num];
     69                     if (cmp_1.num <= 0)
     70                     {
     71                         noth[i] = true;
     72                         total --;
     73                     }
     74                     i = cm;
     75                     continue;
     76                 }
     77             }
     78             bf = 0, cm = i - 1;
     79             while (bf < 1 && cm >= 0)
     80             {
     81                 if (noth[cm --])
     82                     continue;
     83                 bf ++;
     84             }
     85             if (bf == 1 && !noth[i])
     86             {
     87                 node& cmp_1 = pat[i];
     88                 node& cmp_2 = pat[cm+1];
     89                 if ( cmp_1.pile[cmp_1.num-1][0] == cmp_2.pile[cmp_2.num-1][0] )
     90                 {
     91                     cmp_2.pile[cmp_2.num] = "";
     92                     cmp_2.pile[cmp_2.num ++] += cmp_1.pile[--cmp_1.num];
     93                     if (cmp_1.num <= 0)
     94                     {
     95                         noth[i] = true;
     96                         total --;
     97                     }
     98                     i = cm;
     99                     continue;
    100                 }
    101                 else if ( cmp_1.pile[cmp_1.num-1][1] == cmp_2.pile[cmp_2.num-1][1] )
    102                 {
    103                     cmp_2.pile[cmp_2.num] = "";
    104                     cmp_2.pile[cmp_2.num ++] += cmp_1.pile[--cmp_1.num];
    105                     if (cmp_1.num <= 0)
    106                     {
    107                         noth[i] = true;
    108                         total --;
    109                     }
    110                     i = cm;
    111                     continue;
    112                 }
    113             }
    114         }
    115         if (total > 1)
    116             printf ("%d piles remaining:", total);
    117         else printf ("%d pile remaining:", total);
    118         for (i = 0; i < 52; i ++)
    119         {
    120             if (!noth[i])
    121                 printf (" %d", pat[i].num);
    122         }
    123         puts("");
    124     }
    125     return 0;
    126 }
    View Code

    开始时我用得字符数组,而不是字符串,但是用字符数组时,运行到此条语句时cmp_2.pile[cmp_2.num ++] 当cmp_2.num == 50时,自加就变成了25529。直到现在也没弄明白为什么!如果哪位大神路过此地又恰巧知道其中原理时请告知!谢谢。。。

    101 - The Blocks Problem

    题目大意:提供一个大牛的博客http://www.cnblogs.com/devymex/archive/2010/08/04/1792128.html

    解题思路:模拟操作就是了!

    解题代码:

      1 //Author    :Freetion
      2 //file        :101 - The Blocks Problem
      3 
      4 #include <stdio.h>
      5 #include <string.h>
      6 
      7 struct node
      8 {
      9     int top;
     10     int up[30];
     11 }pos[30];
     12 
     13 int main()
     14 {
     15 //    freopen("data.in", "r", stdin);
     16 //    freopen("data.out", "w", stdout);
     17     int n;
     18     char in[2][6];
     19     int p1, on1, p2, on2, ope;
     20     int num1, num2;
     21     while (scanf ("%d", &n) == 1)
     22     {
     23         for (int i = 0; i < n; i ++)
     24         {
     25             pos[i].top = 0;
     26             pos[i].up[pos[i].top ++] = i;
     27         }
     28         while (scanf("%s", in[0]) == 1)
     29         {
     30             if (in[0][0] == 'q')
     31                 break;
     32             scanf ("%d %s %d", &num1, in[1], &num2);
     33             p1 = p2 = -1;
     34             for (int i = 0; i < n; i ++)
     35             {
     36                 for (int j = 0; j < pos[i].top; j ++)
     37                 {
     38                     if (num1 == pos[i].up[j])
     39                         p1 = i, on1 = j;
     40                     if (num2 == pos[i].up[j])
     41                         p2 = i, on2 = j;
     42                     if (p1 != -1 && p2 != -1)
     43                         break;
     44                 }
     45                 if (p1 != -1 && p2 != -1)
     46                         break;
     47             }
     48             if (p1 == p2)
     49                 continue;
     50             if (in[0][0] == 'm')
     51                 ope = 1;
     52             else ope = 3;
     53             if (in[1][1] == 'v')
     54                 ope ++;
     55             if (ope == 1)
     56             {
     57                 for (int i = on1+1; i < pos[p1].top; i ++)
     58                 {
     59                     node& A = pos[pos[p1].up[i]];
     60                     A.up[A.top ++] = pos[p1].up[i];
     61                 }
     62                 pos[p1].top = on1+1;
     63                 for (int i = on2+1; i < pos[p2].top; i ++)
     64                 {
     65                     node& A = pos[pos[p2].up[i]];
     66                     A.up[A.top ++] = pos[p2].up[i];
     67                 }
     68                 pos[p2].top = on2 +1;
     69                     pos[p2].up[pos[p2].top ++] = pos[p1].up[--pos[p1].top];
     70             }
     71             else if (ope == 2)
     72             {
     73                 for (int i = on1+1; i < pos[p1].top; i ++)
     74                 {
     75                     node& A = pos[pos[p1].up[i]];
     76                     A.up[A.top ++] = pos[p1].up[i];
     77                 }
     78                 pos[p1].top = on1+1;
     79                     pos[p2].up[pos[p2].top ++] = pos[p1].up[--pos[p1].top];
     80             }
     81             else if (ope == 3)
     82             {
     83                 for (int i = on2+1; i < pos[p2].top; i ++)
     84                 {
     85                     node& A = pos[pos[p2].up[i]];
     86                     A.up[A.top ++] = pos[p2].up[i];
     87                 }
     88                 pos[p2].top = on2 +1;
     89                 for (int i = on1; i < pos[p1].top; i ++)
     90                 {
     91                     pos[p2].up[pos[p2].top ++] = pos[p1].up[i];
     92                 }
     93                 pos[p1].top = on1;
     94             }
     95             else if (ope == 4)
     96             {
     97                 for (int i = on1; i < pos[p1].top; i ++)
     98                 {
     99                     pos[p2].up[pos[p2].top ++] = pos[p1].up[i];
    100                 }
    101                 pos[p1].top = on1;
    102             }
    103         }
    104         for (int i = 0; i < n; i ++)
    105         {
    106             printf ("%d:", i);
    107             for (int j = 0; j < pos[i].top; j ++)
    108                 printf (" %d", pos[i].up[j]);
    109             printf ("
    ");
    110         }
    111     }
    112     return 0;
    113 }
    View Code

    133 - The Dole Queue

    题目大意:给你一个n个数组成的环,再给出一个顺时钟数的数k,一个逆时钟数的数m。要你从开始的位置同时朝顺时钟和逆时钟两个方向数,将顺时钟数到的第k个数和逆时钟数到的第m个数同时从环中剔除,然后继续数直到环上没有数了。如果数到的是同一个数,则只剔除这一个数。

    解题思路:直接操作,水题!ps:样例中三角型代表的是空格。

    解题代码:

     1 //Author    :Freetion
     2 //file        :133 - The Dole Queue
     3 
     4 #include <stdio.h>
     5 #include <string.h>
     6 using namespace std;
     7 int pp[30];
     8 int k, m;
     9 bool jug[30];
    10 
    11 int main()
    12 {
    13 //    freopen("data.in", "r", stdin);
    14 //    freopen("data.out", "w", stdout);
    15     int k, m, n;
    16     while (~scanf ("%d%d%d", &n, &k, &m) && (k+m+n))
    17     {
    18         memset(jug, true, sizeof (jug));
    19         int shu = 1;
    20         int ni = n;
    21         int total = n;
    22         int num;
    23         while (total)
    24         {
    25             num = 0;
    26             while (num < k)
    27             {
    28                 if (shu > n)
    29                     shu -= n;
    30                 if (jug[shu++])
    31                     num ++;
    32             }
    33             shu --;
    34             num = 0;
    35             while (num < m)
    36             {
    37                 if (ni <= 0)
    38                     ni += n;
    39                 if (jug[ni --])
    40                     num ++;
    41             }
    42             ni ++;
    43             if (ni == shu)
    44             {
    45                 printf ("%3d", ni);
    46                 jug[ni] = false;
    47                 total --;
    48             }
    49             else
    50             {
    51                 printf ("%3d%3d", shu, ni);
    52                 jug[ni] = jug[shu] = false;
    53                 total -= 2;
    54             }
    55             if (total)
    56                 printf (",");
    57         }
    58         printf ("
    ");
    59     }
    60 }
    View Code

    10152 - ShellSort

    题目大意:给出一堆龟壳,我们要将它们按照另一种顺序排好,而每次操作都只能移动一个龟壳,并且只能将其放在这一堆的最上面。问使用最少的移动次数时依次移动龟壳的顺序。

    解题思路:


    解题代码:

     1 //Author    :Freetion
     2 //file        :10152 - ShellSort
     3 
     4 #include <iostream>
     5 #include <stdio.h>
     6 #include <string>
     7 #include <map>
     8 using namespace std;
     9 
    10 const int max_n = 202;
    11 
    12 string str1[max_n], str2[max_n];
    13 
    14 int main()
    15 {
    16 //    freopen("data.in", "r", stdin);
    17 //    freopen("data.out", "w", stdout);
    18     int n, T;
    19     scanf ("%d", &T);
    20     while (T --)
    21     {
    22         scanf ("%d", &n);
    23         getchar();
    24         for (int i = n-1; i >= 0; i --)
    25         {
    26             getline(cin, str1[i]);
    27         }
    28         for (int i = n-1; i >= 0; i --)
    29         {
    30             getline(cin, str2[i]);
    31         }
    32         int j = 0;
    33         for (int i = 0; i < n; i ++)
    34         {
    35             if (str1[i] == str2[j])
    36                 j ++;
    37         }
    38         for (; j < n; j ++)
    39             cout << str2[j] << endl;
    40         printf ("
    ");
    41     }
    42     return 0;
    43 }
    View Code

    673 - Parentheses Balance

    解题思路:将 左括号 入栈,如果碰上 右括号 则看是否与前一个左括号匹配,如果匹配则左括号匹配出栈,直到最后看栈是否空,空则Yes,否则No。

    解题代码:

     1 //Author    :Freetion
     2 //file        :uva-673 Parentheses Balance
     3 
     4 #include <stdio.h>
     5 #include <stack>
     6 #include <string>
     7 #include <iostream>
     8 using namespace std;
     9 string str;
    10 char mat(const char s)
    11 {
    12     if (s == ']')
    13         return '[';
    14     if (s == ')')
    15         return '(';
    16     return 0;
    17 }
    18 
    19 bool jug()
    20 {
    21     stack <char> st;
    22     st.push('0');
    23     int len = str.size();
    24     for (int i = 0; i < len; i ++)
    25     {
    26         if (st.top() != mat(str[i]))
    27             st.push(str[i]);
    28         else st.pop();
    29     }
    30     return st.size() == 1;
    31 }
    32 
    33 int main()
    34 {
    35     int n;
    36     scanf ("%d", &n);
    37     getchar();
    38     while (n --)
    39     {
    40         getline(cin, str);
    41         if (str.size() == 0 || jug())
    42             printf ("Yes
    ");
    43         else printf ("No
    ");
    44     }
    45     return 0;
    46 }
    View Code

    442 - Matrix Chain Multiplication

    题目意思是让我们求矩阵相乘的总次数,另外括号是里面限定了只有两个矩阵!

    解题思路:可以利用上题括号匹配,将先算的矩阵找出来,然后判断是否可以相乘,可以则计算次数,不可以则退出循环。

    解题代码:

     1 //Author    :Freetion
     2 //file        :442 - Matrix Chain Multiplication
     3 
     4 #include <stdio.h>
     5 #include <string.h>
     6 #include <stack>
     7 #include <iostream>
     8 using namespace std;
     9 
    10 struct node
    11 {    
    12     int x, y;
    13 }Matrix[30];
    14 
    15 int main ()
    16 {
    17 //    freopen("data.in", "r", stdin);
    18 //    freopen("data.out", "w", stdout);
    19     int n;
    20     char s[2];
    21     char mul[1000];
    22     while (~scanf ("%d", &n))
    23     {
    24         for (int i = 0; i < n; i ++)
    25         {
    26             scanf ("%s", s);
    27             scanf ("%d%d", &Matrix[s[0]-'A'].x, &Matrix[s[0]-'A'].y);
    28         }
    29         while (~scanf ("%s", mul))
    30         {
    31             int len = strlen(mul);
    32             node temp[30];
    33             int top = 0;
    34             int ans = 0;
    35             bool falg = 1;
    36             for (int i = 0; i < len; i ++)
    37             {
    38                 if (mul[i] >= 'A' && mul[i] <= 'Z')
    39                     temp[top ++] = Matrix[mul[i]- 'A'];
    40                 else if (mul[i] == ')' && top > 1)
    41                 {
    42                     if (temp[top-2].y != temp[top-1].x)
    43                     {    falg = 0;    break;    }
    44                     ans += temp[top-2].y * temp[top-2].x * temp[top-1].y;
    45                     temp[top-2].y = temp[top-1].y;
    46                     top --;
    47                 }
    48             }
    49             if (falg)
    50                 printf ("%d
    ", ans);
    51             else
    52                 printf  ("error
    ");
    53         }
    54     }
    55 }
    View Code

    11111 - Generalized Matrioshkas

    此题与673相似,只是将左括号换成了负数,右括号换成了与之互为相反数的正数。当然依旧需要左右括号匹配,与此同时,这一级数的括号所用的数字,要比下一级括号所用的数字之和要大!

    解题代码:

     1 //Author    :Freetion
     2 //file        :11111 - Generalized Matrioshkas
     3 
     4 #include <stdio.h>
     5 #include <string>
     6 #include <sstream>
     7 #include <iostream>
     8 #include <stack>
     9 using namespace std;
    10 
    11 struct node
    12 {
    13     node(const int &a, const int &b):cap(a), left(b) {}
    14     int cap, left;
    15 };
    16 
    17 int main ()
    18 {
    19     freopen ("data.in", "r", stdin);
    20     freopen ("data.out", "w", stdout);
    21     string line;
    22     while (getline(cin, line))
    23     {
    24         stack <node> ope;
    25         istringstream ss(line);
    26         int t;
    27         bool judge = false;
    28         while (ss >> t)
    29         {
    30             if (t < 0)
    31             {    
    32                 if(ope.empty())
    33                     ope.push(node(-t, -t));
    34                 else
    35                 {
    36                     ope.top().left += t;
    37                     if (ope.top().left <= 0)
    38                     {    judge = 1;    break;    }
    39                     else
    40                         ope.push(node(-t, -t));
    41                 }
    42             }
    43             else
    44             {
    45                 if (ope.empty() || ope.top().cap != t)
    46                 {    judge = 1;    break;    }    
    47                 else
    48                     ope.pop();
    49             }
    50         }
    51         if (judge || !ope.empty())
    52             printf (":-( Try again.
    ");
    53         else printf (":-) Matrioshka!
    ");
    54     }
    55     return 0;
    56 }
    View Code

    11234 - Expressions

    这题我也是百度思路的,所以直接贴代码:

     1 //Author    :Freetion
     2 //file        :11234 - Expressions
     3 //´ËÊǺÃÌ⣡ 
     4 
     5 #include <stdio.h>
     6 #include <string>
     7 #include <stack>
     8 #include <queue>
     9 #include <iostream>
    10 using namespace std;
    11 
    12 struct node
    13 {
    14     char ope;
    15     node *left;
    16     node *right;
    17     node (char s, node *l, node *r)
    18     {
    19         ope = s;
    20         left = l;
    21         right = r;
    22     }
    23     node (char s)
    24     {
    25         ope = s;
    26         left = NULL;
    27         right = NULL;
    28     }
    29 };
    30 
    31 int main()
    32 {
    33     string str;
    34     int T;
    35     scanf ("%d", &T);
    36     getchar();
    37     while (T--)
    38     {
    39         stack <node *> ans;
    40         cin >> str;
    41         int len = str.length();
    42         for (int i = 0; i < len; i ++)
    43         {
    44             if (islower(str[i]))
    45             {
    46                 node *new_node = new node(str[i]);
    47                 ans.push(new_node);
    48             }
    49             else
    50             {
    51                 node *a = ans.top();
    52                 ans.pop();
    53                 node *b = ans.top();
    54                 ans.pop();
    55                 node *new_node = new node(str[i], b, a);
    56                 ans.push(new_node);
    57             }
    58         }
    59         node *root = ans.top();
    60         ans.pop();
    61         queue <node *> p;
    62         p.push(root);
    63         while (!p.empty())
    64         {
    65             node *q = p.front();
    66             p.pop();
    67             if (q -> left != NULL)
    68                 p.push(q -> left);
    69             if (q -> right != NULL)
    70                 p.push(q -> right);
    71             ans.push(q);
    72         }
    73         while (!ans.empty())
    74         {
    75             printf ("%c", ans.top()->ope);
    76             ans.pop();
    77         }
    78         cout << endl;
    79     }
    80     return 0;
    81 }
    View Code

    540 - Team Queue

    题目大意:这题不难但是题意好难搞清楚(当然这是对我来说),看看能否说的清楚:给你一个初始队列,这个队列不同于一般的队列,它由多个队列组成一个大队列,然后依次输入操作,ENQUEUE n,代表将数n加入队列,如果在哪个队列里有与n相等的元素则加入该队列之后,如果没有则加入到最后那个队列之后,也就是输入的第一个队列。DEQUEUE 代表删除操作,删除操作是这样的,是按照队列来进行操作的,按队列先进先出的规则,也就是说哪个队列先加入元素,则先输出哪个队列里的元素。输出元素的规则就是先进先出,哪个元素先加入这个队列,则先输出哪个元素, 直到把加入该队列的元素都输出之后,再输出次优先的队列中的元素。每次只删除一个元素!(应该差不多了)

    解题思路:运用队列来做!

    解题代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string>
     4 #include <queue>
     5 #include <map>
     6 using namespace std;
     7 
     8 int main()
     9 {
    10     int n, k, T = 1;
    11     while (~scanf ("%d", &n), n)
    12     {
    13         map <int, int> num;
    14         queue <int> que[1004];
    15         queue <int> que_num;
    16         printf ("Scenario #%d
    ", T++);
    17         for (int i = 0; i < n; i ++)
    18         {
    19             scanf ("%d", &k);
    20             for (int j =  0; j < k; j ++)
    21             {
    22                 int x;
    23                 scanf ("%d", &x);
    24                 num[x] = i;
    25             }
    26         }
    27         string str;
    28         while (cin >> str && str[0] != 'S')
    29         {
    30             if (str[0] == 'E')
    31             {
    32                 int x;
    33                 scanf ("%d", &x);
    34             //    cout << num[x] << endl;
    35                 if (que[num[x]].empty())
    36                     que_num.push(num[x]);
    37                 que[num[x]].push(x);
    38             //    cout << que_num.size() << endl;
    39             }
    40             else
    41             {
    42                 int t = que_num.front();
    43                 printf ("%d
    ", que[t].front());
    44                 que[t].pop();
    45                 if (que[t].empty())
    46                     que_num.pop();
    47             }
    48         }
    49         printf ("
    ");
    50     }
    51 }
    View Code

    10050 - Hartals

    水题一道

    解题代码:

     1 //Author    :Freetion
     2 //file        :10050 - Hartals
     3 
     4 #include <stdio.h>
     5 #include <iostream>
     6 #include <string.h>
     7 using namespace std;
     8 const int max_n = 3660;
     9 bool ba[max_n];
    10 
    11 int main()
    12 {
    13     int T;
    14     int n, p;
    15     scanf ("%d", &T);
    16     while (T--)
    17     {
    18         scanf ("%d%d", &n, &p);
    19         memset(ba, false, sizeof (ba));
    20         for (int i = 0; i < p; i ++)
    21         {
    22             int h;
    23             scanf ("%d", &h);
    24             for (int j = h; j <= n; j += h)
    25             {
    26                 int wek = (j+6)%7;
    27                 if (wek != 5 && wek != 6)
    28                     ba[j] = true;
    29             }
    30         }
    31         int ans = 0;
    32         for (int i = 0; i <= n; i ++)
    33             if (ba[i])
    34                 ans ++;
    35         printf ("%d
    ", ans);
    36     }
    37     return 0;
    38 }
    View Code

     

  • 相关阅读:
    模拟75 题解
    模拟74 题解
    模拟73 题解
    模拟72 题解
    前端学习:html基础学习二
    前端学习:html基础学习一
    JavaScrip:Function函数编程
    MYSQL:RELPACE用法
    MYSQL:插入记录检查记录是否存在,存在则更新,不存在测插入记录SQL
    OpenCASCADE Curve Length Calculation
  • 原文地址:https://www.cnblogs.com/shengshouzhaixing/p/3241992.html
Copyright © 2020-2023  润新知