地址 https://www.acwing.com/problem/content/653/ios
博覽館正在展出由世上最佳的 M 位畫家所畫的圖畫。ide
wangjy想到博覽館去看這幾位大師的做品。spa
但是,那裏的博覽館有一個很奇怪的規定,就是在購買門票時必須說明兩個數字,a和b,表明他要看展覽中的第 a 幅至第 b 幅畫(包含 a 和 b)之間的全部圖畫,而門票的價錢就是一張圖畫一元。code
爲了看到更多名師的畫,wangjy但願入場後能夠看到全部名師的圖畫(至少各一張)。xml
但是他又想節省金錢。。。blog
做爲wangjy的朋友,他請你寫一個程序決定他購買門票時的 a 值和 b 值。ci
第一行包含兩個整數 N 和 M,表示圖畫總數和畫家數量。leetcode
第二行包含 N 個整數,它們都介於 1 和 M 之間,表明畫做做者的編號。get
輸出兩個整數 a 和 b。it
數據保證有解,若是存在多個解,則輸出 a 最小的那個解。
1≤N≤1061≤N≤106,
1≤M≤20001≤M≤2000
12 5 2 5 3 1 3 2 4 1 1 5 4 3
2 7
主要是考慮使用滑動窗口 使用哈希記錄其中各個畫家出現的次數 可是tle
#include <iostream> #include <map> using namespace std; const int N = 1e6+10; int huaArr[N]; map<int,int> mapm; int n ,m; int cnt = 0; int ans = 1e9; int ansa = 1e9; int ansb = 1e9; int main() { ios::sync_with_stdio(false); cin >> n >> m; for(int i =1;i<= n;i++){ cin >> huaArr[i]; } int l = 1; int r= 0; for(int i =1;i <=n;i++){ //i 幅畫放去l r 區間 if (mapm[huaArr[i]] == 0)//曾經沒有出現過 cnt++; r++; mapm[huaArr[i]]++; //開始進行縮減 while(mapm[huaArr[l]] >=2){ //該副畫 排除區間 mapm[huaArr[l]]--; l++; } if(cnt >= m && r-l+1 < ans){ ans = r-l+1; ansa = l; ansb = r; } } cout << ansa << " " << ansb << endl; return 0; }
後面參考其餘同窗的代碼 (https://www.acwing.com/blog/content/150/)
把本身的map改爲了vector 過了。這也是 oj與leetcode的區別吧
1 #include <iostream> 2 #include <map> 3 #include <vector> 4 using namespace std; 5 6 const int N = 1e6+10; 7 8 vector<int> huaArr(N,0); 9 10 vector<int> v(N,0); 11 int n ,m; 12 13 int cnt = 0; 14 15 int ans = 1e9; 16 int ansa = 1e9; 17 int ansb = 1e9; 18 19 20 int main() 21 { 22 ios::sync_with_stdio(false); 23 cin >> n >> m; 24 for(int i =1;i<= n;i++){ 25 cin >> huaArr[i]; 26 } 27 28 int l = 1; int r= 0; 29 30 for(int i =1;i <=n;i++){ 31 //i 幅畫放去l r 區間 32 if (v[huaArr[i]] == 0)//曾經沒有出現過 33 cnt++; 34 r++; 35 v[huaArr[i]]++; 36 37 //開始進行縮減 38 while(v[huaArr[l]] >=2){ 39 //該副畫 排除區間 40 v[huaArr[l]]--; 41 l++; 42 } 43 44 if(cnt >= m && r-l+1 < ans){ 45 ans = r-l+1; 46 ansa = l; 47 ansb = r; 48 } 49 } 50 51 cout << ansa << " " << ansb << endl; 52 53 54 return 0; 55 }