list:
vector的使用
1039 Course List for Student (25 分)
1047 Student List for Course (25 分)
set的使用
1063 Set Similarity (25 分)
string的使用
1060 Are They Equal (25 分)
map的使用
1100 Mars Numbers (20 分)
1054 The Dominant Color (20 分)
1071 Speech Patterns (25 分)
栈
1051 Pop Sequence (25 分)
队列
1056 Mice and Rice (25 分)
链表
1052 Linked List Sorting (25 分)
1074 Reversing Linked List (25 分)
简单模拟:
1042 Shuffling Machine (20 分)
1046 Shortest Distance (20 common.points)
1065 A+B and C (64bit) (20 分)
1002 A+B for Polynomials (25 分)
1039 Course List for Student (25 分)
题目链接
思路:
注意vector selectCourse[M]和vector selectCourse是不一样的东西。前者相当于是二维数组,后者相当于一维数组。
将学生姓名通过getid函数使每一个姓名都与一个数字相关联(类似hash表的思想)以此数字作为selectCourse的下标,用数组selectCourse[i]去存储对应学生所选课程的编号。
注意vector的使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include<stdio.h> #include<string.h> #include<vector> #include<algorithm> using namespace std; const int N=40010; const int M=26*26*26*10+1; vector<int> selectCourse[M];
int getid(char name[]){ int id=0; for(int i=0;i<3;i++){ id=id*26+(name[i]-'A'); } id=id*10+(name[3]-'0'); return id; } int main(){ char name[5]; int n,k; scanf("%d%d",&n,&k); for(int i=0;i<k;i++){ int course,x; scanf("%d%d",&course,&x); for(int j=0;j<x;j++){ scanf("%s",name); int id=getid(name); selectCourse[id].push_back(course); } }
for(int i=0;i<n;i++){ scanf("%s",name); int id=getid(name); sort(selectCourse[id].begin(),selectCourse[id].end()); printf("%s %d",name,selectCourse[id].size()); for(int j=0;j<selectCourse[id].size();j++){ printf(" %d",selectCourse[id][j]); } printf("\n"); } return 0; }
|
1047 Student List for Course (25 分)
题目链接
思路:
此题的思想与上一题差不多,不过定义的name数组是二维数组,输出name字符串的方法要注意一下,要能透彻的理解vector类似是一个可变长的数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include<stdio.h> #include<vector> #include<string.h> #include<algorithm> using namespace std; const int maxn=40010; const int maxc=2510; vector<int> course[maxc]; char name[maxn][5]; int n;
bool cmp(int a,int b){ return strcmp(name[a],name[b])<0; } int main(){ int renshu,kechengshu,kebianhao; scanf("%d%d",&renshu,&kechengshu); for(int i=0;i<renshu;i++){ scanf("%s %d",name[i],&n); for(int j=0;j<n;j++){ scanf("%d",&kebianhao); course[kebianhao].push_back(i); } } for(int i=1;i<=kechengshu;i++){ printf("%d %d\n",i,course[i].size()); sort(course[i].begin(),course[i].end(),cmp); for(int j=0;j<course[i].size();j++){ printf("%s\n",name[course[i][j]]); } } return 0; }
|
1063 Set Similarity (25 分)
题目链接
思路:
用set存储输入的数字,可以去重,然后用compare函数去对比两个不同的集合中的数字是否相同,如果相同,就使samen++,如果不同,就说明使一个新的元素,所以就让totaln++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #include<stdio.h> #include<set> using namespace std; const int n=55; set<int> st[n]; void compare(int x,int y){ int totaln=st[y].size(),samen=0; for(set<int>::iterator it =st[x].begin();it!=st[x].end();it++){ if(st[y].find(*it)!=st[y].end()) samen++; else totaln++; } printf("%.1f%\n",samen*100.0/totaln); }
int main(){ int setn,setinn; int setshu; scanf("%d",&setn); for(int i=1;i<=setn;i++){ scanf("%d",&setinn); for(int j=0;j<setinn;j++){ scanf("%d",&setshu); st[i].insert(setshu); } } int duibishu,set1,set2; scanf("%d",&duibishu); for(int i=0;i<duibishu;i++){ scanf("%d%d",&set1,&set2); compare(set1,set2); } }
|
1060 Are They Equal (25 分)
题目链接
思路:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| #include<iostream> #include<string> using namespace std; int n; string deal(string s,int &e){ int k=0; while(s.length()>0&&s[0]=='0'){ s.erase(s.begin()); } if(s[0]=='.'){ s.erase(s.begin()); while(s.length()>0&&s[0]=='0'){ s.erase(s.begin()); e--; } }else{ while(k<s.length()&&s[k]!='.'){ k++; e++; } if(k<s.length()){ s.erase(s.begin()+k); } } if(s.length()==0){ e=0; } int num=0; k=0; string res; while(num<n){ if(k<s.length()) res+=s[k++]; else res+='0'; num++; } return res; } int main(){ string s1,s2,s3,s4; cin>>n>>s1>>s2; int e1=0,e2=0; s3=deal(s1,e1); s4=deal(s2,e2); if(s3==s4&&e1==e2){ cout<<"YES 0."<<s3<<"*10^"<<e1<<endl; }else{ cout<<"NO 0."<<s3<<"*10^"<<e1<<" 0."<<s4<<"*10^"<<e2<<endl; } return 0; }``` <a name="a5">1100 Mars Numbers (20 分)</a> <a href="https://pintia.cn/problem-sets/994805342720868352/problems/994805367156883456">题目链接</a> 思路: ```c++ #include<stdio.h> #include<iostream> #include<string> #include<map> using namespace std; string shuzi[13]={"tret","jan","feb","mar","apr","may","jun", "jly","aug","sep","oct","nov","dec"}; string beishuzi[13]={"tret","tam","hel","maa","huh","tou", "kes","hei","elo","syy","lok","mer","jou"};
string numtostr[170]; map<string,int> strtonum; void init(){ for(int i=0;i<13;i++){ numtostr[i]=shuzi[i]; strtonum[shuzi[i]]=i; numtostr[i*13]=beishuzi[i]; strtonum[beishuzi[i]]=i*13; } for(int i=1;i<13;i++){ for(int j=1;j<13;j++){ string str=beishuzi[i]+" "+shuzi[j]; numtostr[i*13+j]=str; strtonum[str]=i*13+j; } } } int main(){ init(); int geshu; scanf("%d%*c",&geshu); while(geshu--){ string str; getline(cin,str); if(str[0]>='0'&&str[0]<='9'){ int num=0; for(int i=0;i<str.length();i++){ num=num*10+(str[i]-'0'); } cout<<numtostr[num]<<endl; }else{ cout<<strtonum[str]<<endl; } } return 0;
}
|
1054 The Dominant Color (20 分)
题目链接
思路:用map比较方便,map是这个数字值与这个数字出现的次数的映射。
注意it迭代器,it->first是数字,it->second是次数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include<stdio.h> #include<map> using namespace std; int main(){ int hang,lie,col; scanf("%d%d",&hang,&lie); map<int,int>count; for(int i=0;i<hang;i++){ for(int j=0;j<lie;j++){ scanf("%d",&col); if(count.find(col)!=count.end()) count[col]++; else count[col]=1; } } int k=0,max=0; for(map<int,int>::iterator it=count.begin();it!=count.end();it++){ if(it->second > max){ k=it->first; max=it->second; } } printf("%d\n",k); return 0; }
|
1071 Speech Patterns (25 分)
题目链接
思路:
与上一题的思路一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #include<stdio.h> #include<iostream> #include<map> #include<string> using namespace std;
bool check(char c){ if(c>='0'&&c<='9') return true; if(c>='A'&&c<='Z') return true; if(c>='a'&&c<='z') return true; return false; }
int main(){ map<string,int> count; string str; getline(cin,str); int i=0; while(i<str.length()){ string word; while(i<str.length()&&check(str[i])==true){ if(str[i]>='A'&&str[i]<='Z'){ str[i]+=32; } word+=str[i]; i++; } if(word!=""){ if(count.find(word)==count.end()) count[word]=1; else count[word]++; } while(i<str.length()&&check(str[i]==false)){ i++; } }
string ans; int max=0; for(map<string,int>::iterator it=count.begin();it!=count.end();it++){ if(it->second>max){ max=it->second; ans=it->first; } } cout<<ans<<" "<<max<<endl; return 0; }
|
1051 Pop Sequence (25 分)
题目链接
思路:
用数组存储输入的数字,用current去指向每一个待出栈元素
最里面一层的while语句是核心判定方法,while循环会一直判定栈顶元素是不是与出栈序列中的current指向的元素相同。如果相同就出栈,如果不同了才会去执行外层的for循环,如果此时for循环成立,则才会再执行st.push(i)语句,即入栈。这里不要理解错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include<stdio.h> #include<stack> using namespace std; const int maxn=1010; int arr[maxn]; stack<int> st; int main(){ int m,n,t; scanf("%d%d%d",&m,&n,&t); while(t--){ while(!st.empty()){ st.pop(); } for(int i=1;i<=n;i++){ scanf("%d",&arr[i]); } int current=1; bool flag=true; for(int i=1;i<=n;i++){ st.push(i); if(st.size()>m){ flag=false; break; } while (!st.empty()&&st.top()==arr[current]){ st.pop(); current++; } } if(st.empty()==true&&flag==true){ printf("YES\n"); }else{ printf("NO\n"); } } return 0; }
|
1056 Mice and Rice (25 分)
题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include<stdio.h> #include<queue> using namespace std; const int maxn=1010; struct mouse{ int weight; int r; }mouse[maxn]; int main(){ int np,ng,order; scanf("%d%d",&np,&ng); for(int i=0;i<np;i++){ scanf("%d",&mouse[i].weight); } queue<int> q; for(int i=0;i<np;i++){ scanf("%d",&order); q.push(order); } int temp=np,group; while(q.size()!=1){ if(temp%ng==0) group=temp/ng; else group=temp/ng+1; for(int i=0;i<group;i++){ int k=q.front(); for(int j=0;j<ng;j++){ if(i*ng+j>=temp) break; int front=q.front(); if(mouse[front].weight>mouse[k].weight){ k=front; } mouse[front].r=group+1; q.pop(); } q.push(k); } temp=group; } mouse[q.front()].r=1; for(int i=0;i<np;i++){ printf("%d",mouse[i].r); if(i<np-1) printf(" "); } return 0; }
|
1052 Linked List Sorting (25 分)
题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include<stdio.h> #include<algorithm> using namespace std; const int maxn=100005; struct Node{ int address,data,next; bool flag; }node[maxn];
bool cmp(Node a,Node b){ if(a.flag==false||b.flag==false){ return a.flag>b.flag; }else{ return a.data<b.data; } } int main(){ for(int i=0;i<maxn;i++){ node[i].flag=false; } int n,begin,address; scanf("%d%d",&n,&begin); for(int i=0;i<n;i++){ scanf("%d",&address); scanf("%d%d",&node[address].data,&node[address].next); node[address].address=address; } int count=0,p=begin; while(p!=-1){ node[p].flag=true; count++; p=node[p].next; } if(count==0){ printf("0 -1"); }else{ sort(node,node+maxn,cmp); printf("%d %05d\n",count,node[0].address); for(int i=0;i<count;i++){ if(i!=count-1){ printf("%05d %d %05d\n",node[i].address,node[i].data,node[i+1].address); }else{ printf("%05d %d -1\n",node[i].address,node[i].data); } } } return 0; }
|
1074 Reversing Linked List (25 分)
题目链接
思路:
将有效结点按照order从0开始排列,无效结点的order都是maxn,再通过sort排序,就可以将有效结点和无效结点排分开来。(要考虑到有无效结点的存在)
因为题目需要每k个结点就要反转一次,所以,我们可以将每k个结点看为一组,我们可以对每一组从后往前的输出结点,但是,关键是每一组的最后一个结点的next的处理:
如果i号结点(假设i号结点是一组中的最后一个结点)不在最后一个完整组中,那么i号结点的next就是(i+2)*k-1,即i+1组的最后一个结点。
如果i号结点是在最后一个完整组中,且其后没有不完整组了,则i的next为-1,
如果i号结点在最后一个不完整组中,且其后还有一组不完整组,则i的next为(i+1)*k,即为不完整组中的第一个结点。
此题输出的格式处理较麻烦。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #include<stdio.h> #include<algorithm> using namespace std; const int maxn=100010; struct Node{ int address,data,next; int order; }node[maxn]; bool cmp(Node a,Node b){ return a.order<b.order; }
int main(){ for(int i=0;i<maxn;i++){ node[i].order=maxn; } int begin,n,k,address; scanf("%d%d%d",&begin,&n,&k); for(int i=0;i<n;i++){ scanf("%d",&address); scanf("%d%d",&node[address].data,&node[address].next); node[address].address=address; }
int p=begin,count=0; while(p!=-1){ node[p].order=count++; p=node[p].next; } sort(node,node+maxn,cmp); n=count;
for(int i=0;i<n/k;i++){ for(int j=(i+1)*k-1;j>i*k;j--){ printf("%05d %d %05d\n",node[j].address,node[j].data,node[j-1].address); } printf("%05d %d",node[i*k].address,node[i*k].data); if(i<n/k-1){ printf("%05d\n",node[(i+2)*k-1].address); }else{ if(n%k==0){ printf("-1\n"); }else{ printf("%05d\n",node[(i+1)*k].address); for(int i=n/k*k;i<n;i++){ printf("%05d %d ",node[i].address,node[i].data); if(i<n-1){ printf("%05d\n",node[i+1].address); }else{ printf("-1\n"); } } } } } return 0; }
|
1042 Shuffling Machine (20 分)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include<stdio.h> const int N=54; int originaln[N+1]; int nextn[N+1]; int finallyn[N+1]; char huase[5]={'S','H','C','D','J'}; int main(){ int k; scanf("%d",&k); for(int i=1;i<=N;i++){ originaln[i]=i; } for(int i=1;i<=N;i++){ scanf("%d",&nextn[i]); } for(int step=0;step<k;step++){ for(int i=1;i<=N;i++){ finallyn[nextn[i]]=originaln[i]; } for(int i=1;i<=N;i++){ originaln[i]=finallyn[i]; } } for(int i=1;i<=N;i++){ if(i!=1) printf(" "); printf("%c%d",huase[(originaln[i]-1)/13],(finallyn[i]-1)%13+1);
} return 0; }
|
1046 Shortest Distance (20 common.points)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include<stdio.h> #include<algorithm> using namespace std; const int maxn=100005; int pointers;
int chaxun; int main(){ int pointerzu[maxn]; int shi=0,zhong=0,zongchang=0; int changbu=0; scanf("%d",&pointers); for(int i=0;i<pointers;i++){ scanf("%d",&pointerzu[i]); zongchang+=pointerzu[i]; } scanf("%d",&chaxun); for(int i=0;i<chaxun;i++){ scanf("%d%d",&shi,&zhong); int chang=0; if(shi>zhong){ swap(shi,zhong); } for(int j=shi-1;j<zhong-1;j++){ chang+=pointerzu[j]; } changbu=zongchang-chang; if(changbu<chang){ chang=changbu; } printf("%d\n",chang); } return 0; }
|
上面的方法里面有for循环的嵌套,在运行的时候可能会运行超时,所以可以优化一下:
1065 A+B and C (64bit) (20 分)
注意:这题要注意溢出的判断,如果两个正数之和为负数,就为正溢出,如果两个负数相加为正数,就为负溢出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include<stdio.h> int main(){ long long a,b,c; int n; int tcase=1; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%lld%lld%lld",&a,&b,&c); long long res=a+b; bool flag; if(a>0&&b>0&&res<0) flag=true; else if(a<0&&b<0&&res>=0) flag=false; else if(res>c) flag=true; else flag=false; if(flag==true) printf("Case #%d: true\n",tcase++); else printf("Case #%d: false\n",tcase++); } return 0; }
|
1002 A+B for Polynomials (25 分)
思路:用数组下标作为次项,对应的数组中存放的是对应此项的系数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include<stdio.h> const int maxn=1111; double p[maxn]={}; int main(){ int count=0; int cixiang=0; double a; scanf("%d",&count); for(int i=0;i<count;i++){ scanf("%d %lf",&cixiang,&a); p[cixiang]+=a; } scanf("%d",&count); for(int i=0;i<count;i++){ scanf("%d %lf",&cixiang,&a); p[cixiang]+=a; } int shu=0; for(int i=0;i<maxn;i++){ if(p[i]!=0) shu++; } printf("%d",shu); for(int i=maxn-1;i>=0;i--){ if(p[i]!=0){ printf(" %d %.1f",i,p[i]); } } return 0; }
|