T1 Chat Server’s Outgoing Traffic
题目
基础的字符串操作
#include<bits/stdc++.h>
using namespace std;
int main(){
string s1;
int i=1,j,k,s=0,t=0;//s计算流量,t计算人数
while(getline(cin,s1)){
if(s1[0]=='+')//如果前缀为+
t++;
else if(s1[0]=='-')//如果前缀为-
t--;
else{//如果是消息
j=0;
while(s1[j]!=':')//向右扫描直到冒号
j++;//指向
s=s+(s1.size()-j-1)*t;//累计流量
}
}
cout<<s<<endl;//输出流量
}
T2 Center Alignment
题目
基础的字符串操作,没思维难度
#include<bits/stdc++.h>
using namespace std;
string s[1007];
int c1,num,p;
int main(){
while(getline(cin,s[++c1]))
num=max(num,int(s[c1].size()));
c1--;
for(int i=0;i<num+2;i++) cout<<'*';
cout<<'\n';
for(int i=1;i<=c1;i++){
cout<<'*';
int l=(num-s[i].size())>>1,r=(num-s[i].size()-l);
if(l!=r) p^=1;
if(l!=r && p==0) swap(l,r);
for(int i=1;i<=l;i++) cout<<" ";
cout<<s[i];
for(int i=1;i<=r;i++) cout<<" ";
cout<<'*'<<endl;
}
for(int i=0;i<num+2;i++) cout<<'*';
cout<<'\n';
}
T3 Longest Regular Bracket Sequence
题目
对于已确定的括号序列,对其逐个加入栈中,用
)
)
)消去
(
(
(并标记为1,最后连续的1就为合法序列,找到最长的即可
#include<bits/stdc++.h>
using namespace std;
char s[1000007];
stack<int> sta;
bool flag[1000007];
int cnt[1000007],MAX;
int main(){
cin>>s;
int len=strlen(s);
for(int i=0;i<len;i++){
if(s[i]=='(') sta.push(i) ;
else if(!sta.empty()) flag[sta.top()]=flag[i]=1,sta.pop();
}
for(int i=0;i<len;i++){
if(flag[i]==1) {
int j=i;
while(flag[j+1]) j++;
cnt[j-i+1]++;
MAX=max(MAX,j-i+1);
i=j;
}
}
printf("%d %d",MAX,MAX==0?1:cnt[MAX]);
}
T4 Follow Traffic Rules
题目
物理题,不多说
#include<bits/stdc++.h>
using namespace std;
double a,v,l,d,w,t1,t2,ans;
inline double F(double x){return x*x;}
inline double f(double v0,double v,double a,double l)
{
double s=(v+v0)*(v-v0)/2/a;
if(s>=l) return (-v0+sqrt(F(v0)+2*a*l))/a;
else return (v-v0)/a+(l-s)/v;
}
signed main()
{
scanf("%lf%lf%lf%lf%lf",&a,&v,&l,&d,&w);
double stp=F(w)/2/a;
if(w>=v||stp>=d) ans=f(0,v,a,l);
else
{
t2=f(w,v,a,l-d);
double tjs=sqrt((2*a*d+F(w))/2/a/a);
if(tjs*a<=v) t1=2*tjs-w/a;
else
{
double sf=F(v)/2/a;
double sl=(v+w)*(v-w)/2/a;
t1=v/a+(v-w)/a+(d-sf-sl)/v;
}
ans=t1+t2;
}
printf("%.12f",ans);
}
T5 Bindian Signalizing
题目
先破环为链
然后对于每一对合法的点对,我们让较矮的山贡献答案,避免重算,我们只需处理出每一座山左边和右边第一座比其高的山即可,注意两山为同一座山的情况即可
最后我们发现仅有相同高度的山未处理,单独处理即可
用单调队列做可以
O
(
n
)
O(n)
O(n)解决这个问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+7;
int n;
ll ans;
int h[N],a[N],l[N],r[N],c[N];
stack<int>sta;
int main(){
scanf("%d",&n);
int MAX,pos;
for(int i=0;i<n;i++) {
scanf("%d",&h[i]);
if(h[i]>MAX){
MAX=h[i];
pos=i;
}
}
for(int i=0;i<=n;i++) a[i]=h[(pos+i)%n];
for(int i=0;i<=n;i++){
while(!sta.empty() && a[sta.top()]<a[i])
r[sta.top()]=i,sta.pop();
sta.push(i);
}
while(!sta.empty()) sta.pop();
for(int i=n;~i;i--){
while(!sta.empty() && a[sta.top()]<a[i])
l[sta.top()]=i,sta.pop();
sta.push(i);
}
while(!sta.empty()) sta.pop();
for(int i=0;i<=n;i++){
while(!sta.empty() && a[sta.top()]<=a[i]){
if(a[sta.top()]==a[i]) c[i]=c[sta.top()]+1;
sta.pop();
}
sta.push(i);
}
// for(int i=1;i<n;i++){
// printf("%d: %d %d %d %d\n",i,a[i],l[i],r[i],c[i]);
// }
for(int i=1;i<n;i++){
int tmp=2;
if(l[i]==0&&r[i]==n) tmp=1;
if(l[i]==0&&r[i]==0) tmp=0;
ans+=c[i]+tmp;
}
printf("%lld\n",ans);
return 0;
}
本文完