您的位置:首页 > 其它

cf#354

2016-05-26 21:10 393 查看

A题

http://codeforces.com/contest/676/problem/A

题意:

让最大的数字和最小的离得最远,只能做一次交换

#include <cstdio>
#include<iostream>
using namespace std;
int main()
{
int ans,n,i,x,y,t;
scanf("%d",&n);
for(i=0;i<n;i++)
{
cin>>t;
if(t==1) x=i;  //1的位置
if(t==n) y=i;  //n的位置
}
ans=max(max(n-1-x,n-1-y),max(x,y));
cout<<ans<<endl;
}


B题(暴力模拟)

题意:

从上往下倒酒,某一酒杯满了之后会留到下一层平分给下一层的左右两个,问某时间满了的水杯有多少个

思路:

刚开始想找数学规律的,但是失败了,还是暴力模拟。第一种可以递归,也可以直接循环,dp[i][j],i代表第i行,j代表第j列,当dp[i][j] = 1时,dp[i+1][j] += dp[i+1][j+1] += (dp[i][j]-1)/2.0;

//循环的思路:
dp[1][1] = n;
for(int i = 1 ; i <= n ;i++)
for (int j = 1 ; j <= i ;j++)
if(dp[i][j] >= 1+ eps)
{
dp[i+1][j] += (dp[i][j]-1) / 2.0;
dp[i+1][j+1] += (dp[i][j]-1) / 2.0;
dp[i][j] = 1;
}


个人认为递归更好理解

#include <cstdio>
#include<cmath>
#include<iostream>
#include<stdio.h>
using namespace std;

int n,t;
double bol[11][11];

void find(int x,int y,double fl)
{
bol[x][y]+=fl;
if(bol[x][y]>1)
{
double mid=(bol[x][y]-1)/2.0;
bol[x][y]=1;
if(x+1<=n)
{
find(x+1,y,mid);
find(x+1,y+1,mid);
}
}
}

int main()
{
int ans=0,i,j,k;
scanf("%d%d",&n,&t);
for(i=0;i<t;i++)
{
find(1,1,1.0);
}

for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
if(fabs(bol[i][j]-1)<0.00001)
ans++;
}
cout<<ans<<endl;
}


C题(尺取)

题意:

给一串由ab构成的序列,允许换k个字母,找最长的子串(连续:substring, 子序列(不连续):subsequence)

题解:

尺取法,a,b各取一次,将a给0,b给1,(第二次相反),solve函数里sum是将b改成a的个数,(sum+=a或者b,改变b时就加了1),尺取过程:不断加长这个序列直到sum超了k,超过之后就从头开始减,减到k为止,然后在往后延伸,传说中的虫子爬爬爬。

#include<iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int t,n,k,i,j,sum,ans=0;
int a[100100];

int solve(int a[])
{
i=j=t=sum=0;
while(j<n)
{
sum+=a[j];
t++;

while(sum>k)
{
sum-=a[i];
i++;
t--;
}
ans=max(ans,t);
j++;
}
return ans;
}

int main()
{
char  s[100010];
cin>>n>>k;
scanf("%s",s);
for(i=0;i<n;i++)
a[i]=s[i]-'a';

int ans1 = solve(a);
for(i=0;i<n;i++)
a[i]=1-a[i];
int ans2 = solve(a);
cout<<max(ans1,ans2)<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: