洛谷P2058 海港 題解
阿新 • • 發佈:2019-03-22
col 每次 targe P20 names 過程 .cn 方式 log 題解
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快,快才是信仰。。。
最後請大家關註我唄,嘿嘿嘿。
洛谷P2058 海港 題解