codeforces 的20道C题

A - Warrior and Archer

CodeForces - 595C

n  偶数  然后n个数字 A B 轮流取一个 A让差变小B让差变大 直到最后2 个   求的是最小剩下的差 

最后剩下的 L R  相距 n/2    求一下最小的就行

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

#define inf 1e9+7
#define MAXN  200100
#define ll __int64

int z[MAXN];

int main()
{

    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&z[i]);
        sort(z+1,z+n+1);
        int mi=z[n/2+1]-z[1];
        for(int i=2;i<=n/2;i++)
            mi=min(mi,z[n/2+i]-z[i]);
        printf("%d
",mi);
    }
    return 0;
}
View Code

C - Day at the Beach

CodeForces - 599C

最多能把这个区间分成多少段使得每段区间排序之后所有的还是排好序的

如果前缀的最大<= 后缀的最小  那么就能分  统计有多少个就行

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

#define inf 1e9+7
#define MAXN  100100
#define ll __int64

int z[MAXN];
int mi[MAXN],mx[MAXN];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&z[i]);
        mi[n]=z[n];
        for(int i=n-1;i>=1;i--)
            mi[i]=min(z[i],mi[i+1]);
        mx[1]=z[1];
        for(int i=2;i<=n;i++)
            mx[i]=max(mx[i-1],z[i]);
        int cnt=0;
        for(int i=1;i<n;i++)
        {
            if(mx[i]<=mi[i+1])
                cnt++;
        }
        printf("%d
",cnt+1);
    }
    return 0;
}
View Code

D - The Two Routes

CodeForces - 602C

有一张n个点的图,任意两个点之间都有一条虚边或实边。现在有两个小朋友想从点1走到点n,一个小朋友只能走虚边,一个小朋友只能走实边。

现在问这两个小朋友都走到终点最少需要多少时间。如果没有合法方案输出-1。

2次spfa

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<queue>
#include<set>
#include<map>
#include<deque>

using namespace std;

#define ll long long
#define inf  1e9+7
#define MAXN 410
#define exp 1e-4

bool z[MAXN][MAXN];
bool vis[MAXN];
int dis[MAXN];
deque<int>q1;

int spfa1(int S,int T)
{
    memset(vis,0,sizeof(vis));
    vis[S]=1;
    q1.push_front(S);
    for(int i=1;i<=T;i++)
        dis[i]=inf;
    dis[S]=0;
    while(!q1.empty())
    {
        int now=q1.front();
        q1.pop_front();
        vis[now]=0;
        for(int i=1;i<=T;i++)
        {
            if(i==now)
                continue;
            if(z[now][i]==1&&dis[i]>dis[now]+1)
            {
                dis[i]=dis[now]+1;
                if(!vis[i])
                {
                    if(!q1.empty())
                    {
                        if(dis[i]<dis[q1.front()])
                            q1.push_front(i);
                        else
                            q1.push_back(i);
                    }
                    else
                        q1.push_front(i);
                    vis[i]=1;
                }
            }
        }
    }
    if(dis[T]==inf)
        return -1;
    return dis[T];
}
int spfa2(int S,int T)
{
    memset(vis,0,sizeof(vis));
    vis[S]=1;
    q1.push_front(S);
    for(int i=1;i<=T;i++)
        dis[i]=inf;
    dis[S]=0;
    while(!q1.empty())
    {
        int now=q1.front();
        q1.pop_front();
        vis[now]=0;
        for(int i=1;i<=T;i++)
        {
            if(i==now)
                continue;
            if(z[now][i]==0&&dis[i]>dis[now]+1)
            {
                dis[i]=dis[now]+1;
                if(!vis[i])
                {
                    if(!q1.empty())
                    {
                        if(dis[i]<dis[q1.front()])
                            q1.push_front(i);
                        else
                            q1.push_back(i);
                    }
                    else
                        q1.push_front(i);
                    vis[i]=1;
                }
            }
        }
    }
    if(dis[T]==inf)
        return -1;
    return dis[T];
}

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            z[a][b]=z[b][a]=1;
        }
        int a=spfa1(1,n);
        int b=spfa2(1,n);
        if(a==-1||b==-1)
            printf("-1
");
        else
            printf("%d
",max(a,b));
    }
    return 0;
}
View Code

E - Alternative Thinking

CodeForces - 604C

给你一个长度为n 的二进制串  能有一次翻转操作  求  可以不连续的  0 1 0     或者  1 0 1  1  这样子间隔的串长度

11011 

11111

110

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

#define inf 1e9+7
#define MAXN  100100
#define ll __int64

char z[MAXN];

int main()
{

    int n;
    while(scanf("%d",&n)!=EOF)
    {
        scanf("%s",z);
        int f1,f2,f3;
        f1=f2=f3=0;
        int ans=1;
        int a=z[0]-'0';
        for(int i=1;i<n;i++)
        {
            int b=z[i]-'0';
            if(a!=b)
            {
                ans++;
                a=b;
            }
            if(i>=2&&z[i]==z[i-1]&&z[i-1]==z[i-2])
                f3=1;
            else if(i>=3&&z[i]==z[i-1]&&z[i-2]==z[i-3]&&z[i-1]!=z[i-2])
                 f2=1;
            else if(i>=1&&z[i]==z[i-1])
                f1++;
        }
        if(f3==1||f2==1)
            ans=ans+2;
        else if(f1>0)
        {
            if(f1>1)
                ans=ans+2;
            else
                ans=ans+1;
        }
        printf("%d
",ans);
    }
    return 0;
}
View Code

F - Sorting Railway Cars

CodeForces - 606C

最长的排好的  其他的就是要重排的

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<queue>
#include<set>
#include<map>

using namespace std;

#define ll long long
#define inf  1e9+7
#define MAXN 100010
#define exp 1e-4

int dp[MAXN];
int z[MAXN];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
            scanf("%d",&z[i]);
        for(int i=1;i<=n;i++)
        {
            dp[z[i]]=dp[z[i]-1]+1;
        }
        int mx=0;
        for(int i=1;i<=n;i++)
            mx=max(mx,dp[i]);
        printf("%d
",n-mx);

    }
    return 0;
}
View Code

H - Harmony Analysis

CodeForces - 610C

构造

坐上=右上=左下   右下=左上取反

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<queue>
#include<set>
#include<map>

using namespace std;

#define ll long long
#define inf  1e15+7
#define MAXN 1000010
#define exp 1e-4

bool z[1050][1050];

int main()
{
    int k;
    z[1][1]=1;
    for(int i=1;i<=9;i++)
    {
        int a=1<<(i-1);
        int b=1<<(i);
        for(int k=1;k<=a;k++)
            for(int j=a+1;j<=b;j++)
            {
                 z[a+k][j-a]=z[k][j]=z[k][j-a];
                 z[a+k][j]=!z[k][j-a];
            }
    }
    while(scanf("%d",&k)!=EOF)
    {
        int en=1<<k;
        for(int i=1;i<=en;i++)
        {
            for(int j=1;j<=en;j++)
                if(z[i][j]==1)
                    printf("+");
                else
                    printf("*");
            printf("
");
        }
    }

    return 0;
}
View Code

J - Peter and Snow Blower

CodeForces - 614C

求圆环面积

最远的点就是最远的点

最进的点可能是直线上的点

A B  圆心 判断A  B  是否为钝角 余弦定理  钝角高就不再三角形里面 取近的点  否则就是 那么算高就行

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

#define inf 1e16+7
#define MAXN  100010
#define ll __int64

double pi=4*atan(1.0);

struct point
{
    double x,y;
}z[MAXN];
double dis(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

int main()
{

    int n;
    double x1,y1;
    while(scanf("%d%lf%lf",&n,&x1,&y1)!=EOF)
    {
        for(int i=0;i<n;i++)
            scanf("%lf%lf",&z[i].x,&z[i].y);
        double mi,mx;
        mx=0;
        mi=inf;
        for(int i=0;i<n;i++)
        {
            mx=max(mx,dis(x1,y1,z[i].x,z[i].y)*dis(x1,y1,z[i].x,z[i].y));
            double a,b,c;
            a=dis(z[(i+1)%n].x,z[(i+1)%n].y,x1,y1);
            b=dis(z[i].x,z[i].y,z[(i+1)%n].x,z[(i+1)%n].y);
            c=dis(z[i].x,z[i].y,x1,y1);
            //printf("%lf %lf %lf 
",a,b,c);
            if(b*b+c*c-a*a<0||a*a+b*b-c*c<0)
            {
                mi=min(mi,a*a);
                mi=min(mi,c*c);
            }
            else
            {
                double l=(a+b+c)/2;
                double s=sqrt(l*(l-a)*(l-b)*(l-c));
                double x=s*2/b;
                mi=min(mi,x*x);
            }
        }

        printf("%.8lf
",(mx-mi)*pi);
    }
    return 0;
}
View Code

K - Watering Flowers

CodeForces - 617C

列举这个点在r1那么 >d  就是在 r2

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

#define inf 1e16+7
#define MAXN  2010
#define ll __int64

struct point
{
    ll x,y;
}z[MAXN];
ll dis(ll x1,ll y1,ll x2,ll y2)
{
    return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
int main()
{
    int n;
    ll x1,y1,x2,y2;
    while(scanf("%d%I64d%I64d%I64d%I64d",&n,&x1,&y1,&x2,&y2)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%I64d%I64d",&z[i].x,&z[i].y);
        ll mx=0;
        ll r1,r2;
        r1=r2=0;
        for(int i=1;i<=n;i++)
            r2=max(r2,dis(x2,y2,z[i].x,z[i].y));
        mx=inf;
        mx=min(mx,r2);
        for(int i=1;i<=n;i++)
            r1=max(r1,dis(x1,y1,z[i].x,z[i].y));
        mx=min(mx,r1);
        for(int i=1;i<=n;i++)
        {
            r1=dis(x1,y1,z[i].x,z[i].y);
            r2=0;
            for(int j=1;j<=n;j++)
            {
                if(j==i)
                    continue;
                if(dis(x1,y1,z[j].x,z[j].y)>r1)
                    r2=max(r2,dis(x2,y2,z[j].x,z[j].y));
            }
            mx=min(mx,r1+r2);
        }
        printf("%I64d
",mx);
    }

    return 0;
}
View Code

M - K-special Tables

CodeForces - 625C

看看例子就知道小的先在左边那几列填上去

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

#define inf 1e16+7
#define MAXN  510
#define ll __int64

int z[MAXN][MAXN];


int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        int sum;
        sum=0;
        int b=k-1;
        int c=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=b;j++)
                z[i][j]=c++;
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=k;j<=n;j++)
                z[i][j]=c++;
        }
        for(int i=1;i<=n;i++)
            sum=sum+z[i][k];
        printf("%d
",sum);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<n;j++)
                printf("%d ",z[i][j]);
            printf("%d
",z[i][n]);
        }
    }
    return 0;
}
View Code

N - Famil Door and Brackets

 CodeForces - 629C 
长度为i ( 比 ) 多 j个 的数目

dp[i][j]=(dp[i-1][j-1]+dp[i-1][j+1])
列举一下左边的长度
#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

#define inf 1000000007
#define MAXN  100100
#define ll __int64

char z[MAXN];
ll dp[2010][2010];

int main()
{

    int n,m;
    dp[0][0]=1;
    for(int i=1;i<=2000;i++)
    {
        dp[i][0]=dp[i-1][1];
        for(int j=1;j<=i;j++)
        {
            dp[i][j]=(dp[i-1][j-1]+dp[i-1][j+1])%inf;
        }
    }
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        scanf("%s",z);
        int pr=-inf;
        int sum=0;
        for(int i=0;i<m;i++)
        {
            if(z[i]==')')
                sum++;
            else
                sum--;
            pr=max(pr,sum);
        }
        sum=0;
        for(int i=m-1;i>=0;i--)
        {
            if(z[i]=='(')
                sum++;
            else
                sum--;
        }
        ll ans=0;
        for(int i=0;i<=n-m;i++)
        {
            for(int j=0;j<=n-m;j++)
            {
                int k=j+sum;
                if(j>=pr&&k<=n-m)
                {
                    ans=(ans+(dp[i][j]*dp[n-m-i][k])%inf)%inf;
                }
            }
        }


        printf("%I64d
",ans);
    }
    return 0;
}
View Code
给你一个初始的序列a[1],a[2],...,a[n] ,请输出经过m次操作后的序列。
每个操作是以下两种之一:
    1 r,将子序列a[1]~a[r] 从小到大排序
    2 r,将子序列a[1]~a[r] 从大到小排序
找到最长的  因为前面的短的没用  
然后找到下一个长的 这个的贡献就是后面那几个排好
#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

#define inf 1e9+7
#define MAXN  200100
#define ll __int64

int z[MAXN];
int b[MAXN];

struct node
{
    int ty,ind;
}mx[MAXN];

int main()
{

    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
              scanf("%d",&z[i]);
              b[i]=z[i];
        }
        int len=1;
        mx[0].ind=0;
        for(int i=1;i<=m;i++)
        {
            int ty,r;
            scanf("%d%d",&ty,&r);
            while(len>=1&&r>=mx[len-1].ind)
                len--;
            mx[len].ty=ty;
            mx[len].ind=r;
            len++;
        }
        mx[len].ind=0;
        len++;
        sort(b+1,b+mx[0].ind+1);
        int l,r;
        l=1;
        r=mx[0].ind;
        for(int i=0;i<len-1;i++)
        {
            int aa=mx[i].ind;
            int bb=mx[i+1].ind;
            if(mx[i].ty==1)
            {
                for(int j=aa;j>bb;j--)
                    z[j]=b[r--];
            }
            else
            {
              //  printf("%d %d
",bb,aa);
                for(int j=aa;j>bb;j--)
                    z[j]=b[l++];
            }
        }

        for(int i=1;i<n;i++)
            printf("%d ",z[i]);
        printf("%d
",z[n]);
    }
    return 0;
}
View Code

P - Watchmen

CodeForces - 651C

x要相同 或者y 相同

x y 相同要去同

#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
#include<stack>
#include<deque>
#include<math.h>
#include<set>
#include<iterator>

using namespace std;

#define inf 1e9+7
#define MAXN  10100
#define ll __int64
typedef pair<int, int> p;
map<int,int>x,y;
map<p,int>m1;

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        x.clear();
        y.clear();
        m1.clear();
        for(int i=1;i<=n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            x[a]++;
            y[b]++;
            m1[p(a,b)]++;
        }
        ll ans=0;
        for(map<int,int>::iterator i=x.begin();i!=x.end();i++)
            ans=ans+(ll)i->second*(i->second-1)/2;
        for(map<int,int>::iterator i=y.begin();i!=y.end();i++)
            ans=ans+(ll)i->second*(i->second-1)/2;
        for(map<p,int>::iterator i=m1.begin();i!=m1.end();i++)
            ans=ans-(ll)i->second*(i->second-1)/2;
        printf("%I64d
",ans);
    }
    return 0;
}
View Code

Q - International Olympiad

CodeForces - 664C

题意是 给出缩写 还原原来是数字 

1989开始 走  后面有规律

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  100100
#define ll __int64

set<ll>s1;
char s[20];
ll ten[15];

int main()
{
    int n;
    ten[0]=1;
    for(int i=1;i<=15;i++)
        ten[i]=ten[i-1]*10;
    while(scanf("%d",&n)!=EOF)
    {
        s1.clear();
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            int len=strlen(s);
            int a=0;
            for(int j=4;j<len;j++)
                a=a*10+s[j]-'0';
            int len1=len-4;
            if(len1==1)
            {
                if(a==9)
                    printf("1989
");
                else
                    printf("199%d
",a);
            }
            else if(len1==2)
            {
                if(a==99)
                    printf("1999
");
                else
                    printf("20%02d
",a);
            }
            else if(len1==3)
            {
                if(a<=98)
                    printf("3%03d
",a);
                else
                    printf("2%03d
",a);
            }
            else if(len1==4)
            {
                if(a<=3098)
                    printf("1%04d
",a);
                else
                    printf("%d
",a);
            }
            else if(len1==5)
            {
                if(a<=13098)
                    printf("1%05d
",a);
                else
                    printf("%d
",a);
            }
            else if(len1==6)
            {
                if(a<=113098)
                    printf("1%06d
",a);
                else
                    printf("%d
",a);
            }
            else if(len1==7)
            {
                if(a<=1113098)
                    printf("1%07d
",a);
                else
                    printf("%d
",a);
            }
            else if(len1==8)
            {
                if(a<=11113098)
                    printf("1%08d
",a);
                else
                    printf("%d
",a);
            }
            else if(len1==9)
            {
                if(a<=111113098)
                    printf("1%09d
",a);
                else
                    printf("%d
",a);
            }

        }
    }
    return 0;
}
View Code

R - Little Artem and Matrix

CodeForces - 669C

反一下过来就行了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  10100
#define ll __int64

struct node
{
    int ty,a,b,c;
}z[MAXN];
int x[110][110];

int main()
{
    int n,m,q;
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        memset(x,0,sizeof(x));
        for(int i=1;i<=q;i++)
        {
            scanf("%d",&z[i].ty);
            if(z[i].ty==3)
                scanf("%d%d%d",&z[i].a,&z[i].b,&z[i].c);
            else
                scanf("%d",&z[i].a);
        }
        for(int i=q;i>=1;i--)
        {
            if(z[i].ty==3)
                x[z[i].a][z[i].b]=z[i].c;
            else
            {
                if(z[i].ty==1)
                {
                    int a=x[z[i].a][m];
                    for(int j=m;j>1;j--)
                        x[z[i].a][j]=x[z[i].a][j-1];
                    x[z[i].a][1]=a;
                }
                else
                {
                    int a=x[n][z[i].a];
                    for(int j=n;j>1;j--)
                        x[j][z[i].a]=x[j-1][z[i].a];
                    x[1][z[i].a]=a;
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<m;j++)
                printf("%d ",x[i][j]);
            printf("%d
",x[i][m]);
        }
    }
    return 0;
}
View Code

S - Reberland Linguistics

CodeForces - 667C

前面至少有5个 后面有两个或者三个字母  而且不能相同 有多少个 这样子的2个的或者三个的   、

dp[i][j]  代表 i  到 i+j 能不能成功

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  10100
#define ll __int64

set<string>s1;
bool dp[MAXN][4];

int main()
{
    string s ;
    while(cin>>s)
    {
        memset(dp,0,sizeof(dp));
        s1.clear();
        int len=s.length();
        dp[len][3]=dp[len][2]=1;
        for(int i=len-2;i>=5;i--)
        {
            if(dp[i+2][3]||dp[i+2][2]&&s.substr(i,2)!=s.substr(i+2,2))
            {
                s1.insert(s.substr(i,2));
                dp[i][2]=1;
            }
            if(dp[i+3][2]||dp[i+3][3]&&s.substr(i,3)!=s.substr(i+3,3))
            {
                s1.insert(s.substr(i,3));
                dp[i][3]=1;
            }
        }
        printf("%d
",s1.size());
        for(set<string>::iterator i=s1.begin();i!=s1.end();i++)
            cout<<*i<<endl;
    }
    return 0;
}
View Code
n*n  能过
#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
#include<stack>
#include<deque>
#include<math.h>

using namespace std;

#define inf 1e9+7
#define MAXN  10100
#define ll __int64


int ans[MAXN];
int z[MAXN];
int now[MAXN];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&z[i]);
        memset(ans,0,sizeof(ans));
        for(int i=1;i<=n;i++)
        {
            memset(now,0,sizeof(now));
            int mx=5001,cnt=0;

            for(int j=i;j<=n;j++)
            {
                now[z[j]]++;
                if(now[z[j]]>cnt)
                {
                    mx=z[j];
                    cnt=now[z[j]];
                }
                else if(now[z[j]]==cnt)
                {
                    mx=min(mx,z[j]);
                }
                ans[mx]++;
            }
        }
        for(int i=1;i<n;i++)
            printf("%d ",ans[i]);
        printf("%d
",ans[n]);
    }

    return 0;
}
View Code

U - Recycling Bottles

CodeForces - 672C

维护A到 瓶子距离 B   垃圾站

然后 A -> 瓶子  ->垃圾站   B  ->瓶子 ->垃圾站 

2个最小距离

为什么是2个  A B可能是同一个 

特例是只有A去捡或者B去 

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  100100
#define ll __int64

struct node
{
    double x,y;

}z[MAXN];

double da[MAXN],db[MAXN],dc[MAXN];

double dis(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

int main()
{
    double xa,ya,xb,yb,xc,yc;
    while(scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&xb,&yb,&xc,&yc)!=EOF)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lf%lf",&z[i].x,&z[i].y);
        int aind1,aind2,bind1,bind2;
        bind1=bind2=aind1=aind2=0;
        double ans=0;
        da[0]=inf;
        db[0]=inf;
        dc[0]=-inf;
        for(int i=1;i<=n;i++)
        {
            da[i]=dis(xa,ya,z[i].x,z[i].y);
            db[i]=dis(xb,yb,z[i].x,z[i].y);
            dc[i]=dis(xc,yc,z[i].x,z[i].y);
            if(da[i]-dc[i]<=da[aind1]-dc[aind1])
            {
                aind2=aind1;
                aind1=i;
            }
            else if(da[i]-dc[i]<da[aind2]-dc[aind2])
            {
                aind2=i;
            }

            if(db[i]-dc[i]<=db[bind1]-dc[bind1])
            {
                bind2=bind1;
                bind1=i;
            }
            else if(db[i]-dc[i]<db[bind2]-dc[bind2])
            {
                bind2=i;
            }
        }
        if(aind1!=bind1)
        {
            for(int i=1;i<=n;i++)
            {
                if(i==aind1)
                {
                    ans=ans+da[i]+dc[i];
                }
                else if(i==bind1)
                {
                    ans=ans+db[i]+dc[i];
                }
                else
                    ans=ans+2*dc[i];
            }
        }
        else
        {
            double ans1=0;
            for(int i=1;i<=n;i++)
            {
                if(i==aind1)
                {
                    ans1=ans1+da[i]+dc[i];
                }
                else if(i==bind2)
                {
                    ans1=ans1+db[i]+dc[i];
                }
                else
                    ans1=ans1+2*dc[i];
            }
            ans=ans1;
            ans1=0;
            for(int i=1;i<=n;i++)
            {
                if(i==aind2)
                {
                    ans1=ans1+da[i]+dc[i];
                }
                else if(i==bind1)
                {
                    ans1=ans1+db[i]+dc[i];
                }
                else
                    ans1=ans1+2*dc[i];
            }
            ans=min(ans,ans1);
        }
        double ans1=0;
        for(int i=1;i<=n;i++)
        {
            if(i==aind1)
                ans1=ans1+da[i]+dc[i];
            else
                ans1=ans1+dc[i]*2;
        }
        ans=min(ans,ans1);
        ans1=0;
        for(int i=1;i<=n;i++)
        {
            if(i==bind1)
                ans1=ans1+db[i]+dc[i];
            else
                ans1=ans1+dc[i]*2;
        }
        ans=min(ans,ans1);
        //printf("%d %d %d %d
",aind1,aind2,bind1,bind2);
        printf("%.7lf
",ans);
    }
    return 0;
}
View Code
前缀和相同 那么可以少移动一次
#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  100100
#define ll __int64

int z[MAXN];
map<ll,int>m1;

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        m1.clear();
        for(int i=1;i<=n;i++)
            scanf("%d",&z[i]);
        int ans=0;
        ll sum=0;
        for(int i=1;i<=n;i++)
        {
            sum=sum+z[i];
            m1[sum]++;
            if(m1[sum]>ans)
                ans=m1[sum];
        }
        printf("%d
",n-ans);
    }
    return 0;
}
View Code

小希有一个长度为n的ab串,他想要找出最长的一个子串使得这个子串中每个字符都相等,他称之为“最优子串”。当然对小希来说这个问题太简单了,于是他加了一个条件:他可以改变这个串中的某些字符,但一次只能改变一个字符,最多能改变k次。小希想要知道,在可以对串进行改变的前提下,这个ab串的“最优子串”的长度是多少。

列举位置 二分最右边的位子  前缀和 

#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
#include<stack>
#include<deque>
#include<math.h>
#include<set>
#include<iterator>

using namespace std;

#define inf 1e9+7
#define MAXN  100100
#define ll __int64

char z[MAXN];
int  a[MAXN],b[MAXN];

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        scanf("%s",z+1);
        int len=n;
        for(int i=1;i<=len;i++)
        {
            if(z[i]=='a')
            {
                a[i]=a[i-1]+1;
                b[i]=b[i-1];
            }
            else
            {
                a[i]=a[i-1];
                b[i]=b[i-1]+1;
            }
        }
        int mx=0;
        for(int i=1;i<=len;i++)
        {
            int l,r;
            l=i;
            r=len;
            int mx1=l;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if((mid-i+1)-(a[mid]-a[i-1])>m)
                    r=mid-1;
                else
                {
                    mx1=max(mx1,mid);
                    l=mid+1;
                }
            }
            mx=max(mx,mx1-i+1);
            l=i;
            r=len;
            mx1=l;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if((mid-i+1)-(b[mid]-b[i-1])>m)
                    r=mid-1;
                else
                {
                    mx1=max(mx1,mid);
                    l=mid+1;
                }
            }
             mx=max(mx,mx1-i+1);
        }
        printf("%d
",mx);
    }
    return 0;
}
View Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include<set>

using namespace std;

#define inf 1000000007
#define MAXN  100100
#define ll __int64

char z[MAXN];

int deal(char a)
{
    int w;
    if(a>='0'&&a<='9')
        w=a-'0';
    else if(a>='A'&&a<='Z')
        w=a-'A'+10;
    else if(a>='a'&&a<='z')
        w=a-'a'+36;
    else if(a=='_')
        w=63;
    else
        w=62;
    int num=0;
    for(int i=1;i<=6;i++)
    {
        if(w%2==0)
            num++;
        w>>=1;
    }
    return num;

}
int main()
{
    while(scanf("%s",z)!=EOF)
    {
        int len=strlen(z);
        ll ans=1;
        for(int i=0;i<len;i++)
        {
            int a=deal(z[i]);
            for(int i=1;i<=a;i++)
                ans=(ans*3)%inf;
        }
        printf("%I64d
",ans);
    }
    return 0;
}
View Code
 
原文地址:https://www.cnblogs.com/cherryMJY/p/7106975.html