天梯赛中的一些题目
思路:没想到的事可以处理我们需要的那部分,也就是存入朋友圈人数小于等于1的人,反向思维
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<set> using namespace std; const int maxx=1e5+10; int a[maxx]={0}; int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++){ int k; scanf("%d",&k); if(k==1){ int num; scanf("%d",&num); }else if(k>1){ for(int i=0;i<k;i++){ int num; scanf("%d",&num); a[num]++; } } } scanf("%d",&n); int sum=0; int flag=0; for(int i=0;i<n;i++){ int num; scanf("%d",&num); if(flag==0&&a[num]==0){ printf("%05d",num); sum++; a[num]=1; flag++; }else if(a[num]==0){ printf(" %05d",num); a[num]=1; sum++; } } if(sum==0){ printf("No one is handsome"); } printf("\n"); }
L2-023 图着色问题 (25 分)
说明:必须是等于k种,不然测试点2是过不了的
代码;
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<map> #include<stack> #include<set> using namespace std; const int maxx=1e5+10; int main(){ int v,e,k; int a[600][600]={0}; scanf("%d %d %d",&v,&e,&k); for(int i=0;i<e;i++){ int x,y; scanf("%d %d",&x,&y); a[x][y]++; a[y][x]++; } int n; scanf("%d",&n); for(int i=0;i<n;i++){ int b[600]={0}; int flag=0; set<int> c; for(int j=1;j<=v;j++){ scanf("%d",&b[j]); c.insert(b[j]); } for(int j=1;j<=v;j++){ for(int p=1;p<=j;p++){ if(a[j][p]>0&&b[j]==b[p]){ flag++; } } } if(flag>0||c.size()!=k){ printf("No\n"); }else{ printf("Yes\n"); } } }
L2-004 这是二叉搜索树吗? (25 分)
说明:判断是否是二叉树,通过s.size(),就可以判断,后序遍历也完成了
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <vector> using namespace std; int a[1500]; vector<int> s; int flag=0; void findd(int l,int r){ if(l>r) return;//终止条件 int pl=l+1,pr=r; if(flag==0){ while(pl<=r&&a[pl]<a[l]) pl++; while(pr>l&&a[pr]>=a[l]) pr--; }else{ while(pl<=r&&a[pl]>=a[l]) pl++;//等号的问题 while(pr>l&&a[pr]<a[l]) pr--; } if(pl-pr!=1){ return; } findd(l+1,pl-1); findd(pr+1,r); s.push_back(a[l]); } int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); } findd(0,n-1); if(s.size()!=n){ flag++; s.clear(); findd(0,n-1); } if(s.size()!=n){ printf("NO\n"); }else{ printf("YES\n"); for(int i=0;i<n;i++){ printf("%d",s[i]); if(i<n-1){ printf(" "); } } } }
L2-006 树的遍历 (25 分)
说明:(1)要用map。指定下标,或者用数组也可以,vector不可以
(2)主要循环遍历的过程就是找到左右子树的位置而已
(3)在递归的过程中,根节点已经被排除在外了,就不应该包括在内了
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<cstring> #include<vector> #include<map> using namespace std; int post[50],in[50]; map<int,int> ans;//要用map。指定下标,或者用数组也可以,vector不可以 int maxx=0; void check(int root,int l,int r,int sign){ if(l>r) return; int k=l; for(k=l;k<r;k++){//主要循环遍历的过程就是找到左右子树的位置而已 if(post[root]==in[k]) break; } ans[sign]=post[root]; maxx=max(sign,maxx); check(root-1-(r-k),l,k-1,2*sign+1);//根节点已经被排除在外了,就不应该包括在内了 check(root-1,k+1,r,2*sign+2); } int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&post[i]); } for(int i=0;i<n;i++){ scanf("%d",&in[i]); } check(n-1,0,n-1,0); int s=0; for(int i=0;i<=maxx;i++){ if(ans[i]>0){ printf("%d",ans[i]); s++; if(s<n){ printf(" "); } } } }