topcoder srm 698 div1 -3

1、定义重复串$S=T+T$,即$S$可以表示成一个串的叠加。给定一个串$s$,可以通过删除字符、修改字符、增加字符来使得其变为重复串。问最少的次数。

思路:首先将$s$分成个串$s_{0},s_{1}$,然后计算将$s_{0},s_{1}$变成一样要多少次操作。

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
#include <assert.h>
using namespace std;

int f[111][111];


void up(int &x,int y)
{
    if(x==-1||x>y) x=y;
}

int cal(string s1,string s2)
{
    const int n=(int)s1.size();
    const int m=(int)s2.size();

    if(n==0) return m;
    if(m==0) return n;

    memset(f,-1,sizeof(f));
    f[0][0]=0;
    for(int i=1;i<=m;++i) f[0][i]=i;
    for(int i=1;i<=n;++i) f[i][0]=i;

    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
        {
            char c1=s1[i-1];
            char c2=s2[j-1];
            up(f[i][j],f[i-1][j]+1);
            up(f[i][j],f[i][j-1]+1);
            up(f[i][j],f[i-1][j-1]+(c1!=c2));
        }
    }
    return f[n][m];
}

class RepeatString
{
public:
    int minimalModify(string s)
    {
        const int n=(int)s.size();
        int ans=n;
        for(int i=0;i<=n;++i)
        {
            ans=min(ans,cal(s.substr(0,i),s.substr(i)));
        }
        return ans;
    }
};

  

2、给出平面上$n$个点的集合$S$,没有三点共线。定义$CH(s)$为包含点集$s$的最小凸包。求这样的点集对$(s_{1},s_{2})$有多少:(1)$s_{1}\in S,s_{2} \in S$;(2)$s_{1},s_{2}$没有交集;(3)$CH(s_{1}),CH(s_{2})$相交。

思路:求出所有的点集对然后减去不相交的。不相交的可以通过枚举两个点$p_{0},p_{1}$来确定一条直线,然后从直线一侧选出一些点跟$p_{0}$组成一个点集,从直线另一侧选出一些点跟$p_{1}$组成一个点集。

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
#include <assert.h>
using namespace std;



const int N=111;
const int mod=1000000007;


int C[N][N],p[N];

void init()
{
    C[0][0]=1;
    for(int i=1;i<N;++i)
    {
        C[i][0]=C[i][i]=1;
        for(int j=1;j<i;++j)
        {
            C[i][j]=C[i-1][j]+C[i-1][j-1];
            if(C[i][j]>=mod) C[i][j]-=mod;
        }
    }

    p[0]=1;
    for(int i=1;i<N;++i)
    {
        p[i]=p[i-1]<<1;
        if(p[i]>=mod) p[i]-=mod;
    }
}

class IntersectingConvexHull
{
public:
    int count(vector <int> x, vector <int> y)
    {
        init();
        const int n=(int)x.size();
        int ans=0;
        for(int i=3;i<=n;++i) for(int j=3;j<=n-i;++j)
        {
            ans+=(long long)C[n][i]*C[n-i][j]%mod;
            if(ans>=mod) ans-=mod;
        }
        for(int i=0;i<n;++i) for(int j=0;j<n;++j) if(i!=j)
        {
            int s[2]={0,0};
            for(int k=0;k<n;++k) if(k!=i&&k!=j)
            {
                long long d=(long long)(x[j]-x[i])*(y[k]-y[i])-(long long)(x[k]-x[i])*(y[j]-y[i]);
                if(d>0) ++s[0];
                else ++s[1];
            }
            if(s[0]<2||s[1]<2) continue;

            int t0=p[s[0]]-1-s[0];
            int t1=p[s[1]]-1-s[1];
            ans-=(long long)t0*t1%mod;
            if(ans<0) ans+=mod;
        }
        return ans;
    }
};

int main()
{

    IntersectingConvexHull p;
    printf("%d\n",p.count({-2,-1,-1,1,1,2},{1,0,2,0,2,1}));
}

  

posted @ 2017-05-17 10:24  朝拜明天19891101  阅读(157)  评论(0编辑  收藏  举报