洛谷P2058 海港 题解
作者:互联网
P2058 海港
题面
NOIP2016第三题
题解
这道题笨蛋就是开一个数组vis[i]表示国籍是i的有几个人,用一个ans来控制国家数,vis[i]减完后若为0就ans--,vis[i]为0时要加就ans++,每次输出ans即可,注意要用tail每次刷新距离当前时间24小时外的船只。于是我们很快就码好一个笨蛋代码
#include<bits/stdc++.h> using namespace std; int n,vis[1005],x,tail=1,ans,k[1005],a[1005][1005],t[1005]; int read(){ int ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar(); return ret*f; } int main(){ n=read(); for(int i=1;i<=n;i++){ t[i]=read(); k[i]=read(); for(int j=1;j<=k[i];j++){ a[i][j]=read(); if(vis[a[i][j]]==0)ans++; vis[a[i][j]]++; } while(t[i]-t[tail]>=86400){ for(int j=1;j<=k[tail];j++){ vis[a[tail][j]]--; if(vis[a[tail][j]]==0)ans--; } tail++; } printf("%d\n",ans); } return 0; }
测评发现笨蛋代码只能拿70分,并不意外......
因为数组大小的原因,很多数据都RE了...数组暴了,我们自然而然的想到了用vector来优化内存。但效率肯定会有所下降。
下面附上vector的代码
#include<bits/stdc++.h> using namespace std; int n,vis[500005],x,tail,ans,k[300005],t[100005]; vector<int> a[100005]; int read(){ int ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar(); return ret*f; } int main(){ n=read(); for(int i=1;i<=n;i++){ t[i]=read(); k[i]=read(); for(int j=1;j<=k[i];j++){ x=read(); if(vis[x]==0)ans++; vis[x]++; a[i].push_back(x); } while(t[i]-t[tail]>=86400){ for(int j=0;j<k[tail];j++){ vis[a[tail][j]]--; if(vis[a[tail][j]]==0)ans--; } tail++; } printf("%d\n",ans); } return 0; }
惊奇的是暴力vector竟然过了,2016的数据是真的水啊!
不求甚解的我当然不会满足与vector的。
通过观察我们发现t[i]是递增的,而且k的总数不超过300000,我们自然而然的就想到了队列来储存每个人的信息,就不用每个时间段都开300000的数组了,只要开一个结构体记下每个人的国籍和来到的时间,用hed和til来控制头和尾,再用笨蛋的方法处理即可啊
(PS:没想到这题这么水)
关于队列
队列其实就是一种数据结构 “栈”无需自己写,递归过程中会自动开系统栈 “队列”需要自己写,一般有两种方式:
- 用数组模拟实现队列
- 用STL中自带的queue(常数比priority_queue大很多,慎用)STL连接
题目中我是这么定义结构体的
struct node{ int ti,xi; }hep[300005];
ti表示来到的时间xi表示国籍
STL队列
定义 queue<int> q; 队列不空 while(!q.empty()) 新元素入队 q.push(m); 取队首元素 q.front(); 队首元素出队 q.pop();
附上我的完美代码哈哈哈哈哈哈哈
#include<bits/stdc++.h> using namespace std; struct node{ int ti,xi; }hep[300005]; int n,t,k,vis[100005],hed,til,ans,x; int read(){ int ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar(); return ret*f; } int main(){ n=read(); for(int i=1;i<=n;i++){ t=read(); k=read(); for(int j=1;j<=k;j++){ x=read(); if(vis[x]==0)ans++; vis[x]++; hep[++til]=(node){t,x}; } while(t-hep[hed].ti>=86400){ vis[hep[hed].xi]--; if(vis[hep[hed].xi]==0)ans--; hed++; } printf("%d\n",ans); } return 0; }
是不是比vector快,快才是信仰。。。
最后请大家关注我呗,嘿嘿嘿。
标签:ch,洛谷,int,题解,ret,vis,ans,P2058,getchar 来源: https://www.cnblogs.com/booksBlog/p/10579747.html