题目链接
1.约瑟夫问题P1996
2.最大子段和P1115
3.表达式括号匹配P1739
4.队列安排P1160
5.后缀表达式P1449
约瑟夫问题是一个很经典的围圈报数的问题,比较简单,直接模拟就可以了
1 #include2 #include 3 #include <string> 4 #include 5 #include 6 #include 7 #include 8 #include
9 #include 10 #include <string.h> 11 12 #define ll long long 13 using namespace std; 14 bool num[105]; 15 int main() 16 { 17 freopen("C:\\Users\\16599\\Desktop\\in.txt","r",stdin); 18 int n,m; 19 cin>>n>>m; 20 int i=1; 21 int cnt=0; 22 int ans=0; 23 while(ans!=n) 24 { 25 if(!num[i]) 26 { 27 cnt++; 28 if(cnt==m) 29 { 30 cout<" "; 31 num[i]=true; 32 cnt=0; 33 ans++; 34 } 35 } 36 i++; 37 if(i==n+1) 38 i=1; 39 } 40 return 0; 41 }
最大子段和是一个入门的DP,状态转移方程可以很容易的写出来,我们假设sum[i]是以i为终点的最大子段和,那么要判断sum[i]就有两种情况
1. 若sum[i-1]<=0,sum[i]=num[i]。若以i-1为终点的最大子段和都小于等于零,不如不取,直接以第i个数作为最大子段和是最大的情况。
2. 若sum[i-1]>0, sum[i]=sum[i-1]+num[i]。若以i-1为终点的最大子段和大于零,自然要取前一段,保证最大。
#include#include #include <string> #include #include #include #include #include #include <string.h> #define ll long long using namespace std; int num[200005]; int sum[200005]; int main() { //freopen("C:\\Users\\16599\\Desktop\\in.txt","r",stdin); int n; int max_num=-99999; cin>>n; for(int i=1;i<=n;i++) cin>>num[i]; for(int i=1;i<=n;i++) { if(sum[i-1]<=0) sum[i]=num[i]; else sum[i]=sum[i-1]+num[i]; max_num=max(sum[i],max_num); } cout< endl; return 0; }
表达式括号匹配,只要满足一个思路即为匹配。
定义一个变量,每出现一个左括号++,每出现一个右括号且当该变量大于零的时候--,当判断完所有字符以后,若该变量等于0,则匹配。这样可以避免)(a+b)(的情况。
#include#include #include <string> #include #include #include #include #include #include <string.h> #define ll long long using namespace std; int main() { //freopen("C:\\Users\\16599\\Desktop\\in.txt","r",stdin); string str; cin>>str; int num=0; bool flag=true; for(int i=0;i ) { if(str[i]=='(') num++; else if(str[i]==')') { if(num>0) num--; else { flag=false; break; } } } if(num==0&&flag) cout<<"YES"<<endl; else cout<<"NO"<<endl; return 0; }
队列安排应该是这里面最难的一题,因为我个人觉得C++的STL里面的list是最难使用的,而这里恰好需要用到list(当然手写链表的大佬请直接忽略)
注意:在C++11的标准下会编译失败,只有在14的标准下才能AC。
//在C++11标准下不能通过,只能在C++14的标准下才能通过 #include#include #include <string> #include #include #include #include #include #include <string.h> #include #define ll long long using namespace std; list <int> v;//创建空链表 using Iter=list <int> ::iterator; list<int> ::iterator it;//创建一个迭代器 Iter pos[100005];//创建一个迭代器的数组,pos[i]是第i号同学的迭代器 bool f[100005]; int main() { //freopen("C:\\Users\\16599\\Desktop\\in.txt","r",stdin); int n,k,p,m; cin>>n; v.push_back(1); pos[1]=v.begin(); for(int i=2;i<=n;i++) { cin>>k>>p; if(p==0) pos[i]=v.insert(pos[k],i); else { auto nextIter=next(pos[k]); pos[i]=v.insert(nextIter,i); } } cin>>m; for(int i=1;i<=m;i++) { cin>>k; f[k]=true; } for(it=v.begin();it!=v.end();it++) { if(!f[*it]) cout<<*it<<" "; } return 0; }
最后一题后缀表达式也比较简单,直接模拟就可以啦
1 #include2 #include 3 #include <string> 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include <string.h> 10 11 #define ll long long 12 using namespace std; 13 stack<int> sta; 14 queue<int> que; 15 int main() 16 { 17 //freopen("C:\\Users\\16599\\Desktop\\in.txt","r",stdin); 18 string str; 19 cin>>str; 20 for(int i=0;i ) 21 { 22 if(str[i]-'0'>=0&&str[i]-'0'<=9) 23 que.push(str[i]-'0'); 24 else if(str[i]=='.'&&!que.empty()) 25 { 26 int a=0; 27 while(!que.empty()) 28 { 29 a=a*10+que.front(); 30 que.pop(); 31 } 32 sta.push(a); 33 } 34 else if(str[i]=='+') 35 { 36 int a,b; 37 a=sta.top(); 38 sta.pop(); 39 b=sta.top(); 40 sta.pop(); 41 sta.push(a+b); 42 } 43 else if(str[i]=='-') 44 { 45 int a,b; 46 a=sta.top(); 47 sta.pop(); 48 b=sta.top(); 49 sta.pop(); 50 sta.push(b-a); 51 } 52 else if(str[i]=='*') 53 { 54 int a,b; 55 a=sta.top(); 56 sta.pop(); 57 b=sta.top(); 58 sta.pop(); 59 sta.push(a*b); 60 } 61 else if(str[i]=='/') 62 { 63 int a,b; 64 a=sta.top(); 65 sta.pop(); 66 b=sta.top(); 67 sta.pop(); 68 sta.push(b/a); 69 } 70 } 71 cout< endl; 72 return 0; 73 }