先说10.2的F题,当时看着像动态规划就做另外的题了,现在看了看别人的思路感觉设计的好巧妙,思路是先用一个结构体存输入顺序和输入的数据还有一个记录答案,用贪心的方法,找现在已经度过的天数中用时最早的那个,然后判断现在的时间和最早的时间是否间隔超过m如果超过就把那天的时间换成现在的,(这个可以用优先队列实现)如果不超过,天数就加一天,在把现在的时间放进队列,记录答案就可以。代码:
#include<bits/stdc++.h> using namespace std; struct mp { int num; int id; int ans; friend bool operator<(const mp p1,const mp p2) { return p1.num >p2.num; } }o; vector<mp>p; bool cmp1(mp p1,mp p2) { return p1.num <p2.num ; } bool cmp2(mp p1,mp p2) { return p1.id <p2.id ; } int main() { int n,m,d; cin>>n>>m>>d; for(int i=0;i<n;i++) { int v; cin>>v; o.id =i; o.num=v; p.push_back(o); } priority_queue<mp>q; sort(p.begin(),p.end(),cmp1); p[0].ans=1; q.push(p[0]); int t=1; for(int i=1;i<n;i++) { o=q.top(); if(p[i].num>o.num +d) { p[i].ans=o.ans; q.pop(); } else { t++; p[i].ans=t; } q.push(p[i]); } sort(p.begin(),p.end(),cmp2); cout<<t<<endl; for(int i=0;i<n;i++) { cout<<p[i].ans<<" "; } }
再说10.3的排座位和社交集群,这两题就是裸的并查集(然而我连并查集都出错...)并查集判断是否在同一个集里是用find找而不是直接用原数组(重要的事要说三遍,但是我懒得打了..)代码:
排座位
#include<bits/stdc++.h> using namespace std; #define LL long long int s[1005],v[1020][1020]; int findf(int x) { return (x==s[x])?x:findf(s[x]); } void unif(int x,int y) { x=findf(x); y=findf(y); if(x!=y)s[y]=x; } int main() { for(int i=0;i<1003;i++) { s[i]=i; } int n,m,k; cin>>n>>m>>k; for(int i=0;i<m;i++) { int a,b,c; cin>>a>>b>>c; if(c==1) { unif(a,b); // cout<<s[a]<<" "<<s[b]<<endl; } else { v[a][b]=1; v[b][a]=1; } } //for(int i=0;i<10;i++)cout<<s[i]<<" "; for(int i=0;i<k;i++) { int a,b; cin>>a>>b; // cout<<s[a]<<" "<<s[b]<<endl; if(findf(s[a])==findf(s[b])&&v[a][b]==0)cout<<"No problem"<<endl; if(findf(s[a])!=findf(s[b])&&v[a][b]==0)cout<<"OK"<<endl; if(findf(s[a])==findf(s[b])&&v[a][b]==1)cout<<"OK but..."<<endl; if(findf(s[a])!=findf(s[b])&&v[a][b]==1)cout<<"No way"<<endl; } }
社交集群
#include<bits/stdc++.h> using namespace std; #define LL long long int s[1005]; int findf(int x) { return (x==s[x])?x:findf(s[x]); } void unif(int x,int y) { x=findf(x); y=findf(y); if(x!=y)s[y]=s[x]; } bool cmp(int a,int b) { return a>b; } int a[1005]; vector<int>p[1005]; int main() { int t; cin>>t; for(int i=0;i<=t;i++) { s[i]=i; } for(int i=1;i<=t;i++) { int n; scanf("%d:",&n); for(int j=0;j<n;j++) { int v; cin>>v; p[v].push_back(i); } } for(int i=0;i<=1000;i++) { if(p[i].size()==0)continue; // cout<<p[i].size()<<endl; for(int j=0;j<p[i].size()-1;j++) { // cout<<p[i][j]<<" "; unif(p[i][j],p[i][j+1]); // cout<<s[p[i][j]]<<" "<<s[p[i][j+1]]<<" "; } // cout<<endl; } for(int i=1;i<=t;i++) { // cout<<s[i]<<endl; a[findf(s[i])]++; } vector<int>q; q.clear(); for(int i=0;i<=t;i++) { if(a[i]>0)q.push_back(a[i]); } sort(q.begin(),q.end(),cmp); cout<<q.size()<<endl; cout<<q[0]; for(int i=1;i<q.size();i++) { cout<<" "<<q[i]; } }
重排链表,emm,怎么说呢,也算是没认真看题吧,忽略了有多余的节点这种情况,改完就可以了。代码:
#include<bits/stdc++.h> using namespace std; #define LL long long struct mp { int addres; int data; int next; int rank; }o[1000005]; bool cmp(mp p1,mp p2) { return p1.rank<p2.rank; } int main() { int num,n; cin>>num>>n; vector<mp>p; p.clear(); for(int i=0;i<n;i++) { int a,b,c; cin>>a>>b>>c; o[a].addres =a; o[a].data =b; o[a].next =c; } int cnt=0; for(;num!=-1;num=o[num].next) { cnt++; o[num].rank=cnt; p.push_back(o[num]); } sort(p.begin(),p.end(),cmp); n=cnt; cnt=0; num=n-1; while(1) { // cout<<num<<endl; if(num>(n-1)/2) { if(cnt==n-1)printf("%05d %d -1\n",p[num].addres,p[num].data); else printf("%05d %d %05d\n",p[num].addres,p[num].data,p[n-1-num].addres); num=n-1-num; } else { if(cnt==n-1)printf("%05d %d -1\n",p[num].addres,p[num].data); else printf("%05d %d %05d\n",p[num].addres,p[num].data,p[n-1-num-1].addres); num=n-1-num-1; } cnt++; if(cnt>=n)break; } }
垃圾箱分类,这题看起来很麻烦(也确实挺麻烦)当时就没做,大体思路就是找所有居民到所有垃圾箱的最短路,如果在某一个垃圾箱有一个最短距离大于给的值就不能作为站点,其他的都成立,在成立的里面找最短距离最小,不然就平均距离最小,不然就id最小,存图也是个小麻烦事,十个垃圾站,存1到10,居民点就在存+10,然后在用Dijktra算法求出每个垃圾站是否满足条件,满足条件就存到数组里,最后在对数组排序,判断数组长度就可以了。(这题样例是向上取整,但是我样例没过,其他的都对了,%.1f好像是向下取整...)代码:
#include<bits/stdc++.h> using namespace std; #define LL long long int n,m,k,ds; struct mp { int minn; int pre; int idd; }o; vector<mp>anss; bool cmp(mp p1,mp p2) { if(p1.minn==p2.minn ) { if(p1.pre ==p2.pre ) { return p1.idd<p2.idd ; } return p1.pre <p2.pre ; } return p1.minn >p2.minn ; } struct edge { int from,to,w; edge(int a,int b,int c) { from=a; to=b;w=c; } }; vector<edge>e[10050]; struct node { int id,dis; node(int a,int b) { id=a;dis=b; } bool operator <(const node a)const { return dis>a.dis; } }; int change(string s) { int o=0; int i; if(s[0]=='G')i=1; else i=0; //cout<<s<<" "<<i<<endl; for(;i<s.size();i++) { o=o*10+s[i]-'0'; } if(s[0]!='G')o=o+10; return o; } void dijktra(int s) { int len[10050]; bool done[10055]; for(int i=0;i<=n+11;i++) { len[i]=0x3f3f3f3f,done[i]=false; } len[s]=0; priority_queue<node>q; q.push(node(s,len[s])); while(!q.empty()) { node u=q.top(); q.pop(); if(done[u.id]) continue; done[u.id]=true; for(int i=0;i<e[u.id].size();i++) { edge y=e[u.id][i]; if(len[y.to ]>y.w+u.dis) { len[y.to]=y.w+u.dis; q.push(node(y.to,len[y.to ])); } } } double min=0x3f3f3f3f,ans=0; int flag=0; for(int i=11;i<=n+10;i++) { if(len[i]<min)min=len[i]; ans+=len[i]; if(len[i]>ds)flag=1; //if(s==3)cout<<len[i]<<" "<<flag<<endl; } if(flag==0) { o.minn=min; o.pre =ans; o.idd=s; anss.push_back(o); // if(s==1)cout<<o.minn<<" "<<o.pre*1.0/(double)n<<endl; } } int main() { anss.clear(); cin>>n>>m>>k>>ds; for(int i=0;i<k;i++) { string a,b; int len; cin>>a>>b>>len; // cout<<a<<" "<<b<<" "<<len<<endl; int vv,bb; vv=change(a); bb=change(b); // cout<<vv<<" "<<bb<<endl; e[vv].push_back(edge(vv,bb,len)); e[bb].push_back(edge(bb,vv,len)); } for(int i=1;i<=m;i++) { dijktra(i); } sort(anss.begin(),anss.end(),cmp); if(anss.size()==0)cout<<"No Solution"<<endl; else { printf("G%d\n",anss[0].idd); printf("%.1lf %.1lf\n",anss[0].minn*1.0,anss[0].pre*1.0/(double)n); } }
浙公网安备 33010602011771号