codeforces#506.div3
阿新 • • 發佈:2018-10-31
A. Many Equal Substrings
求出最長公共前後綴即可(字串的題目,丟)
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<vector> using namespace std; int main() { int n, m; string s; cin >> n >> m >> s; int temp; for(int i = 0; i < n; i++) if(s.substr(0, i) == s.substr(n-i, i)) temp = i; for(int i = 1; i < m; i++) cout << s.substr(0, n - temp); cout << s << endl; return 0; }
B. Creating the Contest
終於碰到了尺取法的題目了。。。
清楚區間轉移規則即可:l=++r
尺取法傳送門:https://blog.csdn.net/hzaukotete/article/details/83449202
#include<bits/stdc++.h> using namespace std; int main() { int n; scanf("%d",&n); int a[200010]; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } if(n==1) { printf("1\n"); return 0; } int l=1,r=2; int len=-1; int sum=1; int pt=a[1]; while(1) { while(2*pt>=a[r]&&r<=n) { pt=a[r]; sum++; r++; } len=max(len,sum); if(r==n+1) { break; } if(n-r+1<=len) { break; } l=r; r++; sum=1; pt=a[l]; } printf("%d\n",len); return 0; }
C. Maximal Intersection
開這個題已經一點多了,接下來還有概率論課,就上網隨便搜題解了,結果都是暴力列舉邊。
這讓我內心感到及其不舒適,於是上課時想了想,發現其實是一個很簡單的一道題。
首先要清楚:
一組邊的最長公共邊=最小的右端點-最大的左端點(想想就知道了)
其次:
如果要使一組邊的最大公共邊改變,只能去掉提供最小右端點的邊或者是提供最大左端點的邊
(最小的右端點和最大的左端點都由一條邊提供的情況特判)
這樣寫整整快了700ms
#include<bits/stdc++.h> using namespace std; struct Node { int l,r; } a[300010]; bool cmp(Node a,Node b) { return a.r<b.r; } priority_queue<int> p1; priority_queue<int,vector<int>,greater<int> > p2; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { int x,y; scanf("%d%d",&x,&y); a[i].l=x; a[i].r=y; p1.push(x); p2.push(y); } sort(a+1,a+n+1,cmp); int len=-1; if(p1.top()==a[1].l&&p2.top()==a[1].r) { p1.pop(); p2.pop(); printf("%d\n",p2.top()-p1.top()); return 0; } int x=p1.top(); p1.pop(); len=max(len,p2.top()-p1.top()); p1.push(x); int xx=p2.top(); p2.pop(); len=max(len,p2.top()-p1.top()); p2.push(xx); if(len>0) printf("%d\n",len); else printf("0\n"); return 0; }
D. Concatenated Multiples
日後補