stl 题目总结
一、圆桌问题
1 、问题:
圆桌上围坐着2n个人。其中n个人是好人,另外n个人是坏人。如果从第一个人开始数数,数到第m个人,则立即处死该人;然后从被处死的人之后开始数数,再将数到的第m个人处死……依此方法不断处死围坐在圆桌上的人。试问预先应如何安排这些好人与坏人的座位,能使得在处死n个人之后,圆桌上围坐的剩余的n个人全是好人。
输入:多组数据,每组数据输入:好人和坏人的人数n(<=32767)、步长m(<=32767);
输出:对于每一组数据,输出2n个大写字母,‘G’表示好人,‘B’表示坏人,50个字母为一行,不允许出现空白字符。相邻数据间留有一空行。
2、设计思路:
1)开辟一个动态数组,并初始化(编号1-2*n).
2) 根据步长、当前数组长度,求出应该“杀死”的人的下标,并按此下标将此人从数组中删去。
3)重复 2)直到数组中仅有 n 个人。
4)开辟一个标志数组,初始化全为 0 ,以动态数组的值作为下标,将对应位置的值改为 1。
5)输出序列,标志数组为 1 输出 ‘G’ 为 0 输出 ‘B’。
代码:
#include<iostream> #include<vector> #include<cstring> using namespace std; int a[70000],n,m,cnt; vector<int> v; int main() { while(cin>>n>>m) { v.clear(); cnt=0; memset(a,0,sizeof(a)); for(int i=1;i<=2*n;i++) v.push_back(i); while(v.size()>n) { cnt=(cnt+m-1)%v.size();///下标 v.erase(v.begin()+cnt);///删除这个死人 /// cout<<cnt<<endl; } vector<int>::iterator it; for(it=v.begin();it!=v.end();it++){ a[*it]=1; /// cout<<*it<<endl; } for(int i=1;i<=2*n;i++) { if ((i-1)%50==0&&i>1) cout<<endl; if (a[i]) cout<<"G"; else cout<<"B"; } cout<<endl; cout<<endl; } return 0; }
4、知识点总结。
1)未知组数据输入: while(cin>>n>>m) Ctrl + c,结束程序。
2)vector:在C++标准模板库中的部分内容它是一个多功能的能够操作多种数据结构和算法的模板类和函数库。作用它能够像容器一样存放各种类型的对象简单地说vector是一个能够存放任意类型的动态数组能够增加和压缩数据。使用vector需要注意以下几点
2-1)、如果你要表示的向量长度较长需要为向量内部保存很多数容易导致内存泄漏而且效率会很低
2-2)、Vector作为函数的参数或者返回值时需要注意它的写法double Distance(vector<int>&a, vector<int>&b) 其中的“&”绝对不能少
3)如果想要使用memset函数,需要在程序的开头添加string.h头文件。介绍memset函数是因为这个函数不是按照常规赋予一个初始值即可,memset函数使用的是按字节赋值,即对每个字节赋同样的值。
二、B - Text Reverse:(文本反转)
1、问题:Ignatius likes to write words in reverse way. Given a single line of text which is written by Ignatius, you should reverse all the words and then output them. (伊格纳修斯喜欢用相反的方式写单词。给出一行由伊格纳提斯写的文本,你应该把所有的单词倒过来,然后输出它们。)
输入:The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow. Each test case contains a single line with several words. There will be at most 1000 characters in a line. (输入包含几个测试用例。输入的第一行是一个整数T,它是测试用例的数量。测试用例如下。每个测试用例包含一行,包含几个单词。一行最多有1000个字符。)
输出:For each test case, you should output the text which is processed. (对于每个测试用例,您应该输出所处理的文本。)
2-1、设计思路:
1)逐个字符读取单词,若字符不是空格或换行或结束标志,让字符进栈。
2)当字符不是空格或换行或结束标志时,输出栈内所有字母。
3)主意控制格式!!!
3、代码:
#include<stdio.h> #include<stack> using namespace std; int main(){ int n; char ch; scanf("%d",&n); getchar(); //!!!吸收回车符 while(n--){ stack<char> s; //定义栈 while(true){ ch=getchar(); //压栈时,一次压入一个字符 if(ch==' '||ch=='\n'||ch==EOF){ while(!s.empty()){ printf("%c",s.top()); s.pop(); //清除栈顶元素 } if(ch=='\n'||ch==EOF) break; //绝对不能少,控制输出结束 printf(" "); } else s.push(ch); } printf("\n"); } return 0; }
4、知识点总结:
1)栈的典型特点:先进后出。
2)基本方法:empty() 堆栈为空则返回真;pop() 移除栈顶元素;push() 在栈顶增加元素;size() 返回栈中元素数目;top() 返回栈顶元素. . . .
三、简单计算器
1、题目:读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入:测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出:对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
2、设计思路:
1)读入第一个数字,和数字后的第一个字符若数字为 0 且字符为 ‘\n’ ,就结束程序。
2)否则,输入后一个字符,和数字,当字符是 ‘+’ 时,将此数存入数组,下标加一;当字符是 ‘-’ 时,将此数的相反数存入数组,下标加一;当字符是 ‘*’ 时,将此数与数组最后一个数进行 * 运算,将结果还存到原位;当字符是 ‘/’ 时,将此数乘1.0与数组最后一个数进行 / 运算,将结果还存到原位;
3)读入下一个字符,若此字符是 ‘\n’ ,将数组中的数相加,按要求输出。否则,重复 2)。
3、代码:
#include<iostream> #include<stdio.h> #include <cstring> using namespace std ; double s[205] ; int main(){ int f=0; char ch=' '; int n=0; char c; int top=0; while(cin>>f){ ch=getchar(); if(f==0&&ch=='\n'){ break; } memset( s , 0 , sizeof( s ) ) ; s[top]=f; while(cin>>c>>n ){ if( c == '+' ) s[++top] = n ; else if( c == '-' ) s[++top] = -n ; else if( c == '*' ) s[top] *= n ; /// * 和 / 操作直接计算好,不算入下一个加减项 else if( c == '/' ) s[top] /= n*1.0 ; cout<<(double)s[top]<<endl; if( getchar() == '\n' ) break ; } double rs=0.00; for(int i=0;i<=top;i++){ rs+=(double)s[i]; } printf("%.2f\n",rs); } return 0; }
4、知识点总结:
1)getchar();与cin>>ch; & scanf("%c",&ch);的区别:
getchar();读入当前文件指针的下一个字符,cin>>ch; & scanf("%c",&ch);默认以空格为分割符读入当前文件指针的下一个字符!
2)printf( "%.2lf\n" , rs ) ;输出浮点数时会按设置的位数进行四舍五入输出。
四、D - ACboy needs your help again!
1、问题:ACboy was kidnapped!!
he miss his mother very much and is very scare now.You can't image how dark the room he was put into is, so poor :(. As a smart ACMer, you want to get ACboy out of the monster's labyrinth.But when you arrive at the gate of the maze, the monste say :" I have heard that you are very clever, but if can't solve my problems, you will die with ACboy." The problems of the monster is shown on the wall: Each problem's first line is a integer N(the number of commands), and a word "FIFO" or "FILO".(you are very happy because you know "FIFO" stands for "First In First Out", and "FILO" means "First In Last Out"). and the following N lines, each line is "IN M" or "OUT", (M represent a integer). and the answer of a problem is a passowrd of a door, so if you want to rescue ACboy, answer the problem carefully!(ACboy被绑架了!他非常想念他的母亲,现在很害怕,你无法想象他被安置在一个多么黑暗的房间里,那么可怜。作为一个聪明的ACMer,你想把ACboy从怪物的迷宫里救出来,但是当你到达迷宫的门口时,蒙斯特说:“我听说你很聪明,但是如果解决不了我的问题,你就会和ACboy一起死。”墙上显示了怪物的问题:每个问题的第一行都是整数N(命令数),还有一个单词“FIFO”或“filo”(你很高兴,因为你知道“FIFO”代表“先进先出”,“filo”表示“先到后出”)。下面的N行,每一行是“in M”或“out”,(m代表整数)。一个问题的答案是一个门的通行证,所以如果你想要拯救ACBOY,请仔细回答这个问题!)
输入:The input contains multiple test cases. The first line has one integer,represent the number oftest cases. And the input of each subproblem are described above.(输入包含多个测试用例。第一行有一个整数,表示测试用例的数量。并对每个子问题的输入进行了描述。)
输出:For each command "OUT", you should output a integer depend on the word is "FIFO" or "FILO", or a word "None" if you don't have any integer.(对于每个命令“out”,您应该输出一个依赖于单词 “FIFO ”或 “filo” 的整数,如果没有任何整数,则输出一个单词“None”。)
2、设计思路:
1)读入案例个数n,和进出形式str,本次案例个数m。
2)如果 str 是 “FIFO” 将数据放到队列中,否则将数据放到栈中。
3)读入字符串,若是 “OUT” 则输出栈顶或队头元素并将其移出,若栈或队列为空,则输出 “None”若是“IN”,读入数据并使其进栈或进队。
4)执行每次 3)后开始下一个案例
3、代码:
#include<stack> #include<stdio.h> #include<queue> #include<cstring> #include<iostream> using namespace std ; int main(){ int n=0; int m=0; int t=0; string str; cin>>n; while(n--){ cin>>m; cin>>str; cout<<str<<endl; if(str=="FIFO"){ queue <int> q; while(m--){ cin>>str; cout<<str<<endl; if(str=="IN"){ cin>>t; q.push(t); }else{ if(q.empty()){ cout<<"None"<<endl; }else{ cout<<q.front()<<endl; q.pop(); } } } }else{ stack <int> s; while(m--){ cin>>str; if(str=="IN"){ cin>>t; s.push(t); }else{ if(s.empty()){ cout<<"None"<<endl; }else{ cout<<s.top()<<endl; s.pop(); } } } } } }