刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第六章 1(Lists)
题目大意:一个人一张张发牌,如果这张牌与这张牌前面的一张或者前面的第三张(后面称之为一位置和三位置)的点数或花式相同,则将这张牌移动到与之对应的位置(优先三位置,也就是说如果一位置与三位置都有以上的性质则移动到三位置之上),移动之后若仍以上的性质,则继续操作,直到已发的所有牌都无法移动之后再继续发牌,(如果一个位置被移空,则删除此位置!)
解题思路:用数组模拟链表,每发一张牌就匹配三位置,如果匹配就移动,否则再看一位置是否满足,如果满足就移动,移动之后,再继续之前的操作,直到所有的都不能移动!如果都不满足,则继续发牌!如此反复直到所有牌都发完!最后只剩下几叠移不动的牌,依次输出每叠的数量。最开始的数是总叠数,如果是1则输出“1 pile remaining: ”其他则输出“6 piles remaining: ”!
解题代码:
- //Author: Freetion
- //file: 127 - "Accordian" Patience
- #include <iostream>
- #include <math.h>
- #include <string.h>
- #include <stdio.h>
- using namespace std;
- struct node
- {
- string pile[];
- int num;
- }pat[];
- bool noth[];
- int main()
- {
- freopen("data.in", "r", stdin);
- freopen("data.out", "w", stdout);
- string tm;
- while (cin >> tm && tm[] != '#')
- {
- memset (noth, false, sizeof (noth));
- int i = ;
- pat[i].pile[] = "";
- pat[i].pile[] += tm;
- pat[i++].num = ;
- for ( ; i < ; i ++)
- {
- pat[i].num = ;
- cin >> pat[i].pile[pat[i].num++];
- }
- /* for (i = 0; i < 52; i ++)
- cout << pat[i].pile[0] << " ";
- for (i = 0; i < 52; i ++)
- cout << pat[i].num << " ";
- */
- int total = ;
- for (i = ; i < ; i ++)
- {
- int bf = , cm = i - ;
- while (bf < && cm >= )
- {
- if (noth[cm --])
- continue;
- bf ++;
- }
- if (bf == && !noth[i])
- {
- node& cmp_1 = pat[i];
- node& cmp_2 = pat[cm+];
- if ( cmp_1.pile[cmp_1.num-][] == cmp_2.pile[cmp_2.num-][] )
- {
- cmp_2.pile[cmp_2.num] = "";
- cmp_2.pile[cmp_2.num ++] += cmp_1.pile[--cmp_1.num];
- if (cmp_1.num <= )
- {
- noth[i] = true;
- total --;
- }
- i = cm;
- continue;
- }
- else if ( cmp_1.pile[cmp_1.num-][] == cmp_2.pile[cmp_2.num-][] )
- {
- cmp_2.pile[cmp_2.num] = "";
- cmp_2.pile[cmp_2.num ++] += cmp_1.pile[--cmp_1.num];
- if (cmp_1.num <= )
- {
- noth[i] = true;
- total --;
- }
- i = cm;
- continue;
- }
- }
- bf = , cm = i - ;
- while (bf < && cm >= )
- {
- if (noth[cm --])
- continue;
- bf ++;
- }
- if (bf == && !noth[i])
- {
- node& cmp_1 = pat[i];
- node& cmp_2 = pat[cm+];
- if ( cmp_1.pile[cmp_1.num-][] == cmp_2.pile[cmp_2.num-][] )
- {
- cmp_2.pile[cmp_2.num] = "";
- cmp_2.pile[cmp_2.num ++] += cmp_1.pile[--cmp_1.num];
- if (cmp_1.num <= )
- {
- noth[i] = true;
- total --;
- }
- i = cm;
- continue;
- }
- else if ( cmp_1.pile[cmp_1.num-][] == cmp_2.pile[cmp_2.num-][] )
- {
- cmp_2.pile[cmp_2.num] = "";
- cmp_2.pile[cmp_2.num ++] += cmp_1.pile[--cmp_1.num];
- if (cmp_1.num <= )
- {
- noth[i] = true;
- total --;
- }
- i = cm;
- continue;
- }
- }
- }
- if (total > )
- printf ("%d piles remaining:", total);
- else printf ("%d pile remaining:", total);
- for (i = ; i < ; i ++)
- {
- if (!noth[i])
- printf (" %d", pat[i].num);
- }
- puts("");
- }
- return ;
- }
开始时我用得字符数组,而不是字符串,但是用字符数组时,运行到此条语句时cmp_2.pile[cmp_2.num ++] 当cmp_2.num == 50时,自加就变成了25529。直到现在也没弄明白为什么!如果哪位大神路过此地又恰巧知道其中原理时请告知!谢谢。。。
题目大意:提供一个大牛的博客http://www.cnblogs.com/devymex/archive/2010/08/04/1792128.html
解题思路:模拟操作就是了!
解题代码:
- //Author :Freetion
- //file :101 - The Blocks Problem
- #include <stdio.h>
- #include <string.h>
- struct node
- {
- int top;
- int up[];
- }pos[];
- int main()
- {
- // freopen("data.in", "r", stdin);
- // freopen("data.out", "w", stdout);
- int n;
- char in[][];
- int p1, on1, p2, on2, ope;
- int num1, num2;
- while (scanf ("%d", &n) == )
- {
- for (int i = ; i < n; i ++)
- {
- pos[i].top = ;
- pos[i].up[pos[i].top ++] = i;
- }
- while (scanf("%s", in[]) == )
- {
- if (in[][] == 'q')
- break;
- scanf ("%d %s %d", &num1, in[], &num2);
- p1 = p2 = -;
- for (int i = ; i < n; i ++)
- {
- for (int j = ; j < pos[i].top; j ++)
- {
- if (num1 == pos[i].up[j])
- p1 = i, on1 = j;
- if (num2 == pos[i].up[j])
- p2 = i, on2 = j;
- if (p1 != - && p2 != -)
- break;
- }
- if (p1 != - && p2 != -)
- break;
- }
- if (p1 == p2)
- continue;
- if (in[][] == 'm')
- ope = ;
- else ope = ;
- if (in[][] == 'v')
- ope ++;
- if (ope == )
- {
- for (int i = on1+; i < pos[p1].top; i ++)
- {
- node& A = pos[pos[p1].up[i]];
- A.up[A.top ++] = pos[p1].up[i];
- }
- pos[p1].top = on1+;
- for (int i = on2+; i < pos[p2].top; i ++)
- {
- node& A = pos[pos[p2].up[i]];
- A.up[A.top ++] = pos[p2].up[i];
- }
- pos[p2].top = on2 +;
- pos[p2].up[pos[p2].top ++] = pos[p1].up[--pos[p1].top];
- }
- else if (ope == )
- {
- for (int i = on1+; i < pos[p1].top; i ++)
- {
- node& A = pos[pos[p1].up[i]];
- A.up[A.top ++] = pos[p1].up[i];
- }
- pos[p1].top = on1+;
- pos[p2].up[pos[p2].top ++] = pos[p1].up[--pos[p1].top];
- }
- else if (ope == )
- {
- for (int i = on2+; i < pos[p2].top; i ++)
- {
- node& A = pos[pos[p2].up[i]];
- A.up[A.top ++] = pos[p2].up[i];
- }
- pos[p2].top = on2 +;
- for (int i = on1; i < pos[p1].top; i ++)
- {
- pos[p2].up[pos[p2].top ++] = pos[p1].up[i];
- }
- pos[p1].top = on1;
- }
- else if (ope == )
- {
- for (int i = on1; i < pos[p1].top; i ++)
- {
- pos[p2].up[pos[p2].top ++] = pos[p1].up[i];
- }
- pos[p1].top = on1;
- }
- }
- for (int i = ; i < n; i ++)
- {
- printf ("%d:", i);
- for (int j = ; j < pos[i].top; j ++)
- printf (" %d", pos[i].up[j]);
- printf ("\n");
- }
- }
- return ;
- }
题目大意:给你一个n个数组成的环,再给出一个顺时钟数的数k,一个逆时钟数的数m。要你从开始的位置同时朝顺时钟和逆时钟两个方向数,将顺时钟数到的第k个数和逆时钟数到的第m个数同时从环中剔除,然后继续数直到环上没有数了。如果数到的是同一个数,则只剔除这一个数。
解题思路:直接操作,水题!ps:样例中三角型代表的是空格。
解题代码:
- //Author :Freetion
- //file :133 - The Dole Queue
- #include <stdio.h>
- #include <string.h>
- using namespace std;
- int pp[];
- int k, m;
- bool jug[];
- int main()
- {
- // freopen("data.in", "r", stdin);
- // freopen("data.out", "w", stdout);
- int k, m, n;
- while (~scanf ("%d%d%d", &n, &k, &m) && (k+m+n))
- {
- memset(jug, true, sizeof (jug));
- int shu = ;
- int ni = n;
- int total = n;
- int num;
- while (total)
- {
- num = ;
- while (num < k)
- {
- if (shu > n)
- shu -= n;
- if (jug[shu++])
- num ++;
- }
- shu --;
- num = ;
- while (num < m)
- {
- if (ni <= )
- ni += n;
- if (jug[ni --])
- num ++;
- }
- ni ++;
- if (ni == shu)
- {
- printf ("%3d", ni);
- jug[ni] = false;
- total --;
- }
- else
- {
- printf ("%3d%3d", shu, ni);
- jug[ni] = jug[shu] = false;
- total -= ;
- }
- if (total)
- printf (",");
- }
- printf ("\n");
- }
- }
题目大意:给出一堆龟壳,我们要将它们按照另一种顺序排好,而每次操作都只能移动一个龟壳,并且只能将其放在这一堆的最上面。问使用最少的移动次数时依次移动龟壳的顺序。
解题思路:
解题代码:
- //Author :Freetion
- //file :10152 - ShellSort
- #include <iostream>
- #include <stdio.h>
- #include <string>
- #include <map>
- using namespace std;
- const int max_n = ;
- string str1[max_n], str2[max_n];
- int main()
- {
- // freopen("data.in", "r", stdin);
- // freopen("data.out", "w", stdout);
- int n, T;
- scanf ("%d", &T);
- while (T --)
- {
- scanf ("%d", &n);
- getchar();
- for (int i = n-; i >= ; i --)
- {
- getline(cin, str1[i]);
- }
- for (int i = n-; i >= ; i --)
- {
- getline(cin, str2[i]);
- }
- int j = ;
- for (int i = ; i < n; i ++)
- {
- if (str1[i] == str2[j])
- j ++;
- }
- for (; j < n; j ++)
- cout << str2[j] << endl;
- printf ("\n");
- }
- return ;
- }
解题思路:将 左括号 入栈,如果碰上 右括号 则看是否与前一个左括号匹配,如果匹配则左括号匹配出栈,直到最后看栈是否空,空则Yes,否则No。
解题代码:
- //Author :Freetion
- //file :uva-673 Parentheses Balance
- #include <stdio.h>
- #include <stack>
- #include <string>
- #include <iostream>
- using namespace std;
- string str;
- char mat(const char s)
- {
- if (s == ']')
- return '[';
- if (s == ')')
- return '(';
- return ;
- }
- bool jug()
- {
- stack <char> st;
- st.push('');
- int len = str.size();
- for (int i = ; i < len; i ++)
- {
- if (st.top() != mat(str[i]))
- st.push(str[i]);
- else st.pop();
- }
- return st.size() == ;
- }
- int main()
- {
- int n;
- scanf ("%d", &n);
- getchar();
- while (n --)
- {
- getline(cin, str);
- if (str.size() == || jug())
- printf ("Yes\n");
- else printf ("No\n");
- }
- return ;
- }
442 - Matrix Chain Multiplication
题目意思是让我们求矩阵相乘的总次数,另外括号是里面限定了只有两个矩阵!
解题思路:可以利用上题括号匹配,将先算的矩阵找出来,然后判断是否可以相乘,可以则计算次数,不可以则退出循环。
解题代码:
- //Author :Freetion
- //file :442 - Matrix Chain Multiplication
- #include <stdio.h>
- #include <string.h>
- #include <stack>
- #include <iostream>
- using namespace std;
- struct node
- {
- int x, y;
- }Matrix[];
- int main ()
- {
- // freopen("data.in", "r", stdin);
- // freopen("data.out", "w", stdout);
- int n;
- char s[];
- char mul[];
- while (~scanf ("%d", &n))
- {
- for (int i = ; i < n; i ++)
- {
- scanf ("%s", s);
- scanf ("%d%d", &Matrix[s[]-'A'].x, &Matrix[s[]-'A'].y);
- }
- while (~scanf ("%s", mul))
- {
- int len = strlen(mul);
- node temp[];
- int top = ;
- int ans = ;
- bool falg = ;
- for (int i = ; i < len; i ++)
- {
- if (mul[i] >= 'A' && mul[i] <= 'Z')
- temp[top ++] = Matrix[mul[i]- 'A'];
- else if (mul[i] == ')' && top > )
- {
- if (temp[top-].y != temp[top-].x)
- { falg = ; break; }
- ans += temp[top-].y * temp[top-].x * temp[top-].y;
- temp[top-].y = temp[top-].y;
- top --;
- }
- }
- if (falg)
- printf ("%d\n", ans);
- else
- printf ("error\n");
- }
- }
- }
11111 - Generalized Matrioshkas
此题与673相似,只是将左括号换成了负数,右括号换成了与之互为相反数的正数。当然依旧需要左右括号匹配,与此同时,这一级数的括号所用的数字,要比下一级括号所用的数字之和要大!
解题代码:
- //Author :Freetion
- //file :11111 - Generalized Matrioshkas
- #include <stdio.h>
- #include <string>
- #include <sstream>
- #include <iostream>
- #include <stack>
- using namespace std;
- struct node
- {
- node(const int &a, const int &b):cap(a), left(b) {}
- int cap, left;
- };
- int main ()
- {
- freopen ("data.in", "r", stdin);
- freopen ("data.out", "w", stdout);
- string line;
- while (getline(cin, line))
- {
- stack <node> ope;
- istringstream ss(line);
- int t;
- bool judge = false;
- while (ss >> t)
- {
- if (t < )
- {
- if(ope.empty())
- ope.push(node(-t, -t));
- else
- {
- ope.top().left += t;
- if (ope.top().left <= )
- { judge = ; break; }
- else
- ope.push(node(-t, -t));
- }
- }
- else
- {
- if (ope.empty() || ope.top().cap != t)
- { judge = ; break; }
- else
- ope.pop();
- }
- }
- if (judge || !ope.empty())
- printf (":-( Try again.\n");
- else printf (":-) Matrioshka!\n");
- }
- return ;
- }
这题我也是百度思路的,所以直接贴代码:
- //Author :Freetion
- //file :11234 - Expressions
- //´ËÊǺÃÌ⣡
- #include <stdio.h>
- #include <string>
- #include <stack>
- #include <queue>
- #include <iostream>
- using namespace std;
- struct node
- {
- char ope;
- node *left;
- node *right;
- node (char s, node *l, node *r)
- {
- ope = s;
- left = l;
- right = r;
- }
- node (char s)
- {
- ope = s;
- left = NULL;
- right = NULL;
- }
- };
- int main()
- {
- string str;
- int T;
- scanf ("%d", &T);
- getchar();
- while (T--)
- {
- stack <node *> ans;
- cin >> str;
- int len = str.length();
- for (int i = ; i < len; i ++)
- {
- if (islower(str[i]))
- {
- node *new_node = new node(str[i]);
- ans.push(new_node);
- }
- else
- {
- node *a = ans.top();
- ans.pop();
- node *b = ans.top();
- ans.pop();
- node *new_node = new node(str[i], b, a);
- ans.push(new_node);
- }
- }
- node *root = ans.top();
- ans.pop();
- queue <node *> p;
- p.push(root);
- while (!p.empty())
- {
- node *q = p.front();
- p.pop();
- if (q -> left != NULL)
- p.push(q -> left);
- if (q -> right != NULL)
- p.push(q -> right);
- ans.push(q);
- }
- while (!ans.empty())
- {
- printf ("%c", ans.top()->ope);
- ans.pop();
- }
- cout << endl;
- }
- return ;
- }
题目大意:这题不难但是题意好难搞清楚(当然这是对我来说),看看能否说的清楚:给你一个初始队列,这个队列不同于一般的队列,它由多个队列组成一个大队列,然后依次输入操作,ENQUEUE n,代表将数n加入队列,如果在哪个队列里有与n相等的元素则加入该队列之后,如果没有则加入到最后那个队列之后,也就是输入的第一个队列。DEQUEUE 代表删除操作,删除操作是这样的,是按照队列来进行操作的,按队列先进先出的规则,也就是说哪个队列先加入元素,则先输出哪个队列里的元素。输出元素的规则就是先进先出,哪个元素先加入这个队列,则先输出哪个元素, 直到把加入该队列的元素都输出之后,再输出次优先的队列中的元素。每次只删除一个元素!(应该差不多了)
解题思路:运用队列来做!
解题代码:
- #include <iostream>
- #include <stdio.h>
- #include <string>
- #include <queue>
- #include <map>
- using namespace std;
- int main()
- {
- int n, k, T = ;
- while (~scanf ("%d", &n), n)
- {
- map <int, int> num;
- queue <int> que[];
- queue <int> que_num;
- printf ("Scenario #%d\n", T++);
- for (int i = ; i < n; i ++)
- {
- scanf ("%d", &k);
- for (int j = ; j < k; j ++)
- {
- int x;
- scanf ("%d", &x);
- num[x] = i;
- }
- }
- string str;
- while (cin >> str && str[] != 'S')
- {
- if (str[] == 'E')
- {
- int x;
- scanf ("%d", &x);
- // cout << num[x] << endl;
- if (que[num[x]].empty())
- que_num.push(num[x]);
- que[num[x]].push(x);
- // cout << que_num.size() << endl;
- }
- else
- {
- int t = que_num.front();
- printf ("%d\n", que[t].front());
- que[t].pop();
- if (que[t].empty())
- que_num.pop();
- }
- }
- printf ("\n");
- }
- }
水题一道
解题代码:
- //Author :Freetion
- //file :10050 - Hartals
- #include <stdio.h>
- #include <iostream>
- #include <string.h>
- using namespace std;
- const int max_n = ;
- bool ba[max_n];
- int main()
- {
- int T;
- int n, p;
- scanf ("%d", &T);
- while (T--)
- {
- scanf ("%d%d", &n, &p);
- memset(ba, false, sizeof (ba));
- for (int i = ; i < p; i ++)
- {
- int h;
- scanf ("%d", &h);
- for (int j = h; j <= n; j += h)
- {
- int wek = (j+)%;
- if (wek != && wek != )
- ba[j] = true;
- }
- }
- int ans = ;
- for (int i = ; i <= n; i ++)
- if (ba[i])
- ans ++;
- printf ("%d\n", ans);
- }
- return ;
- }
刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第六章 1(Lists)的更多相关文章
- 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 1(String)
第一题:401 - Palindromes UVA : http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8 ...
- 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 3(Sorting/Searching)
第一题:340 - Master-Mind Hints UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Item ...
- 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 2(Big Number)
这里的高精度都是要去掉前导0的, 第一题:424 - Integer Inquiry UVA:http://uva.onlinejudge.org/index.php?option=com_onlin ...
- 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第六章 2(Binary Trees)
112 - Tree Summing 题目大意:给出一个数,再给一颗树,每个头节点的子树被包含在头节点之后的括号里,寻找是否有从头节点到叶子的和与给出的数相等,如果有则输出yes,没有输出no! 解题 ...
- 算法竞赛入门经典第二版 TeX中的引号 P47
#include<bits/stdc++.h> using namespace std; int main(){ ; while( (c = getchar()) !=EOF) //get ...
- 算法竞赛入门经典第二版 蛇形填数 P40
#include<bits/stdc++.h> using namespace std; #define maxn 20 int a[maxn][maxn]; int main(){ ; ...
- 算法竞赛入门经典第二版 竖式问题 P42
#include<bits/stdc++.h> using namespace std; int inset(char *s,int num) { //判断数字是否在数字集中 int le ...
- 算法竞赛入门经典第二版 回文词P49
#include<bits/stdc++.h> using namespace std; char rev[]="A 3 HIL JM O 2TUVWXY51SE Z 8 &qu ...
- 算法竞赛入门经典第二版第二章习题-(练习Java和C++语法)
习题2-1水仙花数(daffodil) 输出1000-999中所有的水仙花数.若三位数ABC满足ABC = A3+B3+C3,则称其为水仙花数. Java: package suanfa; publi ...
随机推荐
- java读取各类型的文件
java读取各类型的文件 用到的几个包 bcmail-jdk14-132.jar/bcprov-jdk14-132.jar/checkstyle-all-4.2.jar/FontBox-0.1.0-d ...
- Python性能优化的20条建议 (转载)
优化算法时间复杂度 算法的时间复杂度对程序的执行效率影响最大,在Python中可以通过选择合适的数据结构来优化时间复杂度,如list和set查找某一个元素的时间复杂度分别是O(n)和O(1).不同的场 ...
- shell-IF判断
#!/bin/bash echo "-----------------strat---------------" read -p "Enter a number:&quo ...
- ORACLE 分区表简介
参考链接:http://blog.csdn.net/ziwen00/article/details/9158725ORACLE-分区表 此文从以下几个方面来整理关于分区表的概念及操作: 1.表空间及分 ...
- 企业该如何进行高效IT运维管理
企业该如何进行高效IT运维管理 在企业内部也是一样,当大量的生产和经营数据集中在数据中心,一旦人们与数据中心因为IT故障而失去联系,停滞的也许不是个人应用受阻这样简单的后果.我们谁也不想看到自己企业的 ...
- 使用JSON的数据格式
在说JSON之前,我们先来看一下在javascript中创建对象的方式,也就是创建对象的字面量表示法.我们知道js中有五种基本的数据类型,分别是: Undefined(变量可能没有声明或者赋值) ...
- 查看图片真正的格式,在不知道扩展名的情况下区分是jpeg还是bmp
用系统自带的画图软件打开图片,然后按文件-->另存为就会弹出保存窗口.保存窗口的保存类形就是"照片真正的格式".
- Object:
所有类的直接或者间接父类,Java认为所有的对象都具备一些基本的共性内容,这些内容可以不断的向上抽取,最终就抽取到了一个最顶层的类中的,该类中定义的就是所有对象都具备的功能. 具体方法: 1,bool ...
- 网络攻防工具介绍——Wireshark
网络攻防工具介绍 Wireshark 简介 Wireshark(前称Ethereal)是一个网络封包分析软件.它是一个理想的开源多平台网络协议分析工具.网络封包分析软件的功能是撷取网络封包,并尽可能显 ...
- VS(C++)编程遇到的错误集合
编译错误 1.error C1010: 原因:没有在文件开头添加include "stdafx.h". 2.error C2440: "=": 无法从" ...