A. Chat Server's Outgoing Traffic
题目地址:http://codeforces.com/contest/5/problem/A
题目大意:见原题。
算法讨论:用STL的string和map维护。
Code:
#include <cstdio>
#include <cstring>
#include <set>
#include <string>
using namespace std;
int ans,pos;
char s[1000];
set<string> Set;
int main(){
while (fgets(s,1000,stdin)!=NULL){
int l=strlen(s);
while (s[l-1]=='\n' || s[l-1]=='\r') l--;
s[l]='\0';
if (s[0]=='+') Set.insert(string(s+1));
else if (s[0]=='-') Set.erase(string(s+1));
else{
for (int i=0;i<l;++i)
if (s[i]==':') pos=i;
ans+=Set.size()*(l-pos-1);
}
}
printf("%d\n",ans);
return 0;
}
B. Center Alignment
题目地址:http://codeforces.com/contest/5/problem/B
题目大意:见原题。
算法讨论:比较坑的一点是当左右空格数之和为奇数时,第一次空格左少右多,第二次左多右少,第三次左少右多,以此类推。
Code:
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
using namespace std;
bool f;
int n,len;
char s[10000];
string str[10000];
int main(){
#ifndef ONLINE_JUDGE
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
#endif
while (fgets(s,10000,stdin)!=NULL){
int l=strlen(s);
while (s[l-1]=='\n' || s[l-1]=='\r') l--;
s[l]='\0';
str[++n]=string(s);
len=max(len,l);
}
for (int i=1;i<=len+2;++i) printf("*");
puts("");
for (int i=1;i<=n;++i){
printf("*");
if ((len-str[i].length())%2==0){
for (int j=1;j<=(len-str[i].length())/2;++j) printf(" ");
cout<<str[i];
for (int j=1;j<=(len-str[i].length())/2;++j) printf(" ");
}
else if (!f){
for (int j=1;j<=(len-str[i].length())/2;++j) printf(" ");
cout<<str[i];
for (int j=1;j<=(len-str[i].length())/2+1;++j) printf(" ");
f=1;
}
else{
for (int j=1;j<=(len-str[i].length())/2+1;++j) printf(" ");
cout<<str[i];
for (int j=1;j<=(len-str[i].length())/2;++j) printf(" ");
f=0;
}
puts("*");
}
for (int i=1;i<=len+2;++i) printf("*");
puts("");
return 0;
}
C. Longest Regular Bracket Sequence
题目地址:http://codeforces.com/contest/5/problem/C
题目大意:给出一个括号序列,问最长的合法子串的长度是多少,并且这样的最长子串有多少个。
算法讨论:dp思想,f[i]表示到i为止的最长合法子串的长度。用栈维护即可。
Code:
#include <cstdio>
#include <cstring>
#include <stack>
#define N 1000000
using namespace std;
char s[N+10];
int l,ans,num,f[N+10];
stack<int> st;
int main(){
scanf("%s",s);
l=strlen(s);
for (int i=0;i<l;++i)
if (s[i]=='(') st.push(i+1);
else if (!st.empty()){
int t=st.top();
st.pop();
f[i+1]=f[t-1]+i+1-t+1;
}
for (int i=1;i<=l;++i)
if (f[i]>ans) ans=f[i],num=1;
else if (f[i]==ans) num++;
if (!ans) printf("0 1\n");
else printf("%d %d\n",ans,num);
return 0;
}
D. Follow Traffic Rules
题目地址:http://codeforces.com/contest/5/problem/D
题目大意:一条长l的路,距起点距离为d的点的限速为w,全程限速为v,最大加速度为a,问起点到终点的最短时间。
算法讨论:物理必修一,分类讨论。
Code:
#include <cstdio>
#include <cmath>
using namespace std;
double a,v,l,d,w,vmax,t1,t2,s,s1,s2;
int main(){
scanf("%lf%lf%lf%lf%lf",&a,&v,&l,&d,&w);
if (w>v) w=v;
if (w*w/2/a>=d){
if (v*v/a/2>l) printf("%.9lf\n",sqrt(2*l/a));
else printf("%.9lf\n",v/a+(l-v*v/2/a)/v);
return 0;
}
double vmax=sqrt(a*d+w*w/2);
if (vmax<=v){
t1=vmax/a+(vmax-w)/a;
s=(v*v-w*w)/2/a;
if (s<=l-d){
t2=(v-w)/a+(l-d-s)/v;
printf("%.9lf\n",t1+t2);
}
else printf("%.9lf\n",t1+(-2*w+sqrt(4*w*w-8*a*(d-l)))/2/a);
return 0;
}
s1=d-(2*v*v-w*w)/2/a;
t1=s1/v+v/a+(v-w)/a;
s2=(v*v-w*w)/2/a;
if (s2<=l-d){
t2=(v-w)/a+(l-d-s2)/v;
printf("%.9lf\n",t1+t2);
}
else printf("%.9lf\n",t1+(-2*w+sqrt(4*w*w-8*a*(d-l)))/2/a);
return 0;
}
E. Bindian Signalizing
题目地址:http://codeforces.com/contest/5/problem/E
题目大意:一个圆上有n个点,每个点有一个高度,两个点能相互看见当且仅当两个点之间的点都不高于这2个点,问有几对点能相互看见。
算法讨论:
先找到最高的那个点,以这个点将圆拉成链,可以证明这样操作后的答案不变。
记录一个点的左边第一个比它高的点l[i],右边第一个比它高的点r[i]和i到r[i]之间高度等于i的点数c[i]。
其中r[i]和c[i]的求解可用dp思想。
Code:
#include <cstdio>
using namespace std;
#define N 1000000
int n,cnt,Max,which,h[N+10],a[N+10],l[N+10],r[N+10],c[N+10];
long long ans;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;++i){
scanf("%d",&h[i]);
if (h[i]>Max) Max=h[i],which=i;
}
a[1]=h[which];
cnt=1;
for (int i=which+1;i<=n;++i) a[++cnt]=h[i];
for (int i=1;i<which;++i) a[++cnt]=h[i];
for (int i=n;i;--i){
r[i]=i+1;
while (r[i]<=n && a[i]>a[r[i]]) r[i]=r[r[i]];
if (r[i]<=n && a[i]==a[r[i]]) c[i]=c[r[i]]+1,r[i]=r[r[i]];
}
for (int i=1;i<=n;++i){
l[i]=i-1;
while (l[i]>0 && a[i]>=a[l[i]]) l[i]=l[l[i]];
}
for (int i=1;i<=n;++i){
ans+=(long long)c[i];
if (a[i]==a[1]) continue;
if (r[i]==n+1 && l[i]==1) ans++;
else ans+=2LL;
}
printf("%I64d\n",ans);
return 0;
}
By Charlie Pan
Mar 12,2014