Practice_17_07_基础STL
A_排序
输入一行数字,‘5’看为空格,将一行数字分为若干非负整数。对这些分割得到的整数从大到小排序输出
多组测试用例输入。
思路:字符输入,放到stack,遇5对stack字符处理然后放入快速队列,遇'\n'输出。
这题我wa了很多次,先是多个5连在一起的情况没有处理把两个连续的5中间的整数记成了0...后来又发现忘记考虑存在一行数字的结尾不是5的情况.....
AC代码:
/****************************** *2018_01_22_17:00 *Topology *nmu17冬-07[基础STL]_A-排序 *WA_未考虑单行结尾不为5的情况 提交时记得注释freopen *AC ******************************/ #include <cstdio> #include <iostream> #include <queue> #include <stack> typedef long long ll; using namespace std; stack<char> num; priority_queue<ll,vector<ll>,greater<ll> > pq; int main(){ char a; ll siz,i,t,x,sumx; // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); while((a=getchar())!=EOF){ //cout<<a<<endl; if(a=='5'){ //cout<<'a'<<endl; siz=num.size(); t=1; sumx=0; for(i=0;i<siz;i++){ x= (int)num.top()-'0'; num.pop(); x=x*t; t=t*10; sumx=sumx+x; } if(siz!=0) pq.push(sumx); } else if(a=='\n'){ //cout<<'b'<<endl; if(num.size()!=0){ siz=num.size(); t=1; sumx=0; for(i=0;i<siz;i++){ x= (int)num.top()-'0'; num.pop(); x=x*t; t=t*10; sumx=sumx+x; } pq.push(sumx); } siz=pq.size(); for(i=0;i<siz-1;i++){ sumx=pq.top(); cout<<sumx<<" "; pq.pop(); } sumx=pq.top(); printf("%d\n",sumx); pq.pop(); } else { // cout<<'c'<<endl; num.push(a); } } return 0; }
B_Parentheses Balance
旧题,详见Cpp_queue vector stack duque map set_Note 02_K_balance
C_Team Queue
团队队列中,每个元素属于一个团队,如果元素进入队列,先搜索是否有该元素的团队在队列中,如果在队列中该元素放入团队末尾,否则放入队列末尾。团队队列出队按照队列的顺序从头到尾处理。
命令:ENQUEUE x -将元素x输入到团队队列中;
DEQUEUE -输出队首并删除;
STOP -测试用例结束
思路:用map记录每个元素所在的团队名,并用team记录团队第一个输入元素之间的顺序,输出时按照team记录的团队顺序输出每个团队里的元素。
AC代码:
/*************************** *2018_01_22_20:40 *Topology *nmu17冬-07[基础STL]_C-Team Queue *AC queue_map ***************************/ #include <cstdio> #include <iostream> #include <queue> #include <map> using namespace std; int main(){ int t,n,i,cas=1; string s; while(scanf("%d",&t)!=EOF&&t){ printf("Scenario #%d\n",cas++); map<int,int> ma; for(i=0;i<t;i++){ scanf("%d",&n); while(n--){ int x; scanf("%d",&x); ma[x]=i; } } queue<int> team; queue<int> q[1005]; while(cin>>s&&s!="STOP"){ if(s=="ENQUEUE"){ int t; scanf("%d",&t); int t1=ma[t]; if(q[t1].empty()) team.push(t1); q[t1].push(t); } else{ int t2=team.front(); printf("%d\n",q[t2].front()); q[t2].pop(); if(q[t2].empty()) team.pop(); } } printf("\n"); } return 0; }
D_Error Correction
输入n阶0-1矩阵,若每行每列各自的和均为偶数,输出“OK”;若只改变矩阵的一个元素可以使得矩阵满足第一种情况,输出改变元素的位置;否则,输出“Corrupt”。
思路:若仅一行一列和为奇数,则可改变。
AC代码:
/********************************************************* *18_01_23_12:41 *Topology *nmu17冬-07[基础STL]_D_Error Correction *Pending_AC queue *********************************************************/ #include <cstdio> #include <iostream> #include <queue> using namespace std; int a[103][103]; int main(){ int n,i,j,tr,tc,t; while(scanf("%d",&n)!=EOF&&n){ queue<int>row; queue<int>col; for(i=0;i<n;i++){ tr=0; for(j=0;j<n;j++){ scanf("%d",&a[i][j]); tr=tr+a[i][j]; } if(tr%2==1){ t=i+1; row.push(t); } } for(i=0;i<n;i++){ tc=0; for(j=0;j<n;j++){ tc=tc+a[j][i]; } if(tc%2==1){ t=i+1; col.push(t); } } if(row.size()==0&&col.size()==0) printf("OK\n"); else if(row.size()==1&&col.size()==1) printf("Change bit (%d,%d)\n",row.front(),col.front()); else printf("Corrupt\n"); } return 0; }
E_Dogs' Candies
“1 x y”表示向盒子中放入甜度为x酸度为y的糖果;“0 x y”表示狗想知道自己的口味(x,y)所能匹配到的适合的糖在盒子中的位置;“-1 x y”表示狗王拿出了箱子中属性为x,y的糖果。
最多10个测试样例。输出the maximal deliciousness degree of the best candy for the dog.
思路:结构体、list
AC代码:
/*************************************** *18_01_23_15:08 *Topology *nmu17冬-07[基础STL]_E_Dogs' Candies *TLEx2 WAxn list *AC... ***************************************/ #include <iostream> #include <cstdio> #include <list> typedef long long ll; using namespace std; struct cd{ll a,b;}c; list<cd> li; list<cd>::iterator it; int main(){ int n; ll t,x,y,ans; std::ios::sync_with_stdio(false); std::cin.tie(0); //不加速会导致超时,写了这行之后scanf和cin不能共用 while(cin>>n&&n){ li.clear(); while(n--){ cin>>t>>x>>y; if(t==1){ c.a=x; c.b=y; li.push_front(c); } if(t==-1){ for(it=li.begin();it!=li.end();it++){ c=*it; if(c.a==x&&c.b==y){ li.erase(it); break; } } } if(t==0){ ans=-0x3f3f3f3f3f3f3f3f; for(it=li.begin();it!=li.end();it++){ c=*it; ll an; an=c.a*x+c.b*y; if(an>ans) ans=an; } cout<<ans<<endl; } } } return 0; }
F_Rails
旧题,详见Cpp_queue vector stack duque map set_Note 02_J_rails
G_Subsequence
找出满足子序列最大元素和最小元素之间的差值在区间[m,k]上的最长子序列和。
多组输入。
思路:用双端队列存最大和最小在数列中的位置然后判断是否在要求的范围内
AC代码:
/********************************************************* *18_01_23_10:00 *Topology *nmu17冬-07[基础STL]_G_Subsequence *AC 用两个双端队列分别储存数组中最大值最小值的位置(暴力 *********************************************************/ #include <iostream> #include <cstdio> #include <queue> #include <algorithm> using namespace std; int a[100000]; int main(){ int n,m,k,last,ans; int i,j; while(scanf("%d %d %d",&n,&m,&k)!=EOF){ for(i=0;i<n;i++) scanf("%d",&a[i]); ans=0;last= -1; deque<int>maxa; deque<int>mina; for(i=0;i<n;i++){ // cout<<"a"<<endl; while(!maxa.empty()&&a[i]>a[maxa.back()]) maxa.pop_back(); while(!mina.empty()&&a[i]<a[mina.back()]) mina.pop_back(); maxa.push_back(i); // cout<<"c"<<endl; mina.push_back(i); // cout<<a[maxa.front()]-a[mina.front()]<<endl; while(!maxa.empty()&&!mina.empty()&&a[maxa.front()]-a[mina.front()]>k){ // cout<<"b"<<endl; if(maxa.front()>mina.front()){ last=mina.front(); mina.pop_front(); } else if(maxa.front()<mina.front()){ last=maxa.front(); maxa.pop_front(); } else { last=mina.front(); mina.pop_front(); maxa.pop_front(); } } if(!maxa.empty()&&!mina.empty()&&a[maxa.front()]-a[mina.front()]>=m){ //cout<<"d"<<endl; ans=max(ans,i-last); } } printf("%d\n",ans); } return 0; }
H_Sliding Window
确定长度的滑动窗口,输出一行数字在滑动窗口中的最小值、最大值。
思路:最早是想直接比对子序列得到最大值最小值,储存到队列中最后再输出(被注释掉的代码),后来被判超时就换了个思路,用双端队列分别存最小值和最大值,还是TLE....后来发现用G++提交TLE,用C++提交AC...._(:з」∠)_....也许....原来的思路用C++也能AC??(后来也没试....
AC代码:
/********************************************************* *18_01_23_13:50 *Topology *nmu17冬-07[基础STL]_H_Sliding Window *TLExn G++提交TLE,C++提交AC *(╯‵□′)╯︵┻━┻ *********************************************************/ #include <cstdio> #include <iostream> #include <queue> using namespace std; int a[1000004]; deque<int>maxa; deque<int>mina; int main(){ //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int n,k,i; scanf("%d %d",&n,&k); for(i=0;i<n;i++){ scanf("%d",&a[i]); // if(i>=k-1){ // mina=maxa=a[i-k+1]; //cout<<mina<<" "; // for(j=i-k+2;j<=i;j++){ //cout<<a[j]<<" "; // if(a[j]<mina) mina=a[j]; // if(a[j]>maxa) maxa=a[j]; // } //cout<<"max "<<maxa<<" min "<<mina<<endl; // maxq.push(maxa); // minq.push(mina); // } } // while(!minq.empty()){ // printf("%d ",minq.front()); // minq.pop(); // } // printf("\n"); // while(!maxq.empty()){ // printf("%d ",maxq.front()); // maxq.pop(); // } // printf("\n"); for(i=0;i<n;i++){ while(!mina.empty()&&a[i]<a[mina.back()]) mina.pop_back(); mina.push_back(i); if(i>=k-1){ while(!mina.empty()&&mina.front()<i-k+1) mina.pop_front(); printf("%d ",a[mina.front()]); } } printf("\n"); for(i=0;i<n;i++){ while(!maxa.empty()&&a[i]>a[maxa.back()]) maxa.pop_back(); maxa.push_back(i); if(i>=k-1){ while(!maxa.empty()&&maxa.front()<i-k+1) maxa.pop_front(); printf("%d ",a[maxa.front()]); } } printf("\n"); return 0; }