首页 > 代码库 > codeforces 803

codeforces 803

A n*n的填满0的矩阵  让你放k个1  替代0 字典序最大  按对角线对称 

从左往右从上往下直接走就可以了

技术分享
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cstring>
#include<iostream>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<iterator>
#include<stack>

using namespace std;

#define ll   long long
#define MAXN  110
#define inf  2000000007

int z[105][105];

int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        memset(z,0,sizeof(z));
        for(int i=1;i<=n;i++)
        {
            for(int j=i;j<=n;j++)
            {
                if(i==j)
                {
                    if(k>=1)
                    {
                        k--;
                        z[i][j]=1;
                    }
                }
                else
                {
                    if(k>=2)
                    {
                        k--;
                        k--;
                        z[i][j]=z[j][i]=1;
                    }
                }
            }
        }
        if(k>0)
            printf("-1\n");
        else
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<n;j++)
                    printf("%d ",z[i][j]);
                printf("%d\n",z[i][n]);
            }
        }
    }
    return 0;
}
View Code

N

N个数   求每个数到0的最小距离  其中至少有1个0

l[i]=l[i-1]+1   如果w[i]不是0  否则l[i]=0;

r[i]=r[i+1]+1如果w[i]不是0  否则r[i]=0;

然后取小的那个就行了

技术分享
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cstring>
#include<iostream>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<iterator>
#include<stack>

using namespace std;

#define ll   long long
#define MAXN  200010
#define inf  2000000007

int z[MAXN];
int l[MAXN];
int r[MAXN];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        l[0]=r[n+1]=inf;
        for(int i=1;i<=n;i++)
        {
            l[i]=r[i]=inf;
            scanf("%d",&z[i]);
        }
        for(int i=1;i<=n;i++)
        {
            if(z[i]==0)
                l[i]=0;
            else
                l[i]=l[i-1]+1;
        }
        for(int i=n;i>=1;i--)
        {
            if(z[i]==0)
                r[i]=0;
            else
                r[i]=r[i+1]+1;
        }
        for(int i=1;i<n;i++)
            printf("%d ",min(l[i],r[i]));
        printf("%d\n",min(l[n],r[n]));

    }
    return 0;
}
View Code

C  总要卡住  思维果然是弱项

k个严格递增的数和能否是n  并且最大公约数尽量大

n=d*x  x是n的因子  那么 每个数就是   d1*x   d2*x   dk*x

显然n>=(1+k)*k/2      1 ...k   那么  n*2/k/(k+1)>=x  x是因子  然后就是列举n的因子  从大到小  最后结果  x  2*x  3*x  n-前面的

技术分享
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cstring>
#include<iostream>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<iterator>
#include<stack>

using namespace std;

#define ll   long long
#define MAXN  200010
#define inf  2000000007
ll n,k;
int chick(ll a)
{
    if(a>n*2/k/(k+1))
        return 0;
    ll now=n;
    now=n-k*a*(k-1)/2;
    if(now<=0)
        return 0;
    if((now>(k-1)*a)&&(now%a==0))
    {
        for(int i=1;i<k;i++)
            printf("%lld ",i*a);
        printf("%lld\n",now);
         return 1;
    }
    return 0;
}

int main()
{
    scanf("%lld%lld",&n,&k);
    int i;
    double en=sqrt(n);
    for(i=1;i<=en;i++)
    {
        if(n%i==0)
        {
            if(chick(n/i))
                return 0;
        }

    }
    for(;i>=1;i--)
    {
        if(n%i==0)
        {
            if(chick(i))
                return 0;
        }
    }
    printf("-1\n");
    return 0;
}
View Code

D

一个广告  字符串  只能以 ‘-‘ ‘ ‘ 分隔   要分成n行 使得最长的最短

显然是要二分长度的  那么问题就是l  ~ l+mid-1  这段区间最右边的能分割的点在log(n)的时间里求出来    好像n也是行的nlog(n)也能过

我上了线段树  维护这个区间最右边的能分割的点 

技术分享
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cstring>
#include<iostream>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<iterator>
#include<stack>

using namespace std;

#define ll   long long
#define MAXN  1000010
#define inf  1000000007

struct node
{
    int l,r,ind,z;
}tree[MAXN<<2];

char z[MAXN];
int len;
void Push_up(int a)
{
    if(tree[a<<1|1].z==1)
    {
        tree[a].z=1;
        tree[a].ind=tree[a<<1|1].ind;
    }
    else if(tree[a<<1].z==1)
    {
        tree[a].z=1;
        tree[a].ind=tree[a<<1].ind;
    }
    else
    {
        tree[a].z=-1;
        tree[a].ind=-1;
    }
}
void Build(int l,int r,int a)
{
    tree[a].l=l;
    tree[a].r=r;
    if(l==r)
    {
        if(z[l]== ||z[l]==-||l==len)
        {
            tree[a].ind=l;
            tree[a].z=1;
        }
        else
        {
            tree[a].ind=-1;
            tree[a].z=-1;
        }
        return ;
    }
    int mid=(l+r)>>1;
    Build(l,mid,a<<1);
    Build(mid+1,r,a<<1|1);
    Push_up(a);
}
int Ques(int l,int r,int a1,int b1,int a)
{
    if(a1<=l&&r<=b1)
        return tree[a].ind;

    int mid=(l+r)>>1;
    int mx=-1;
    if(a1<=mid)
        mx=max(mx,Ques(l,mid,a1,b1,a<<1));
    if(b1>mid)
        mx=max(mx,Ques(mid+1,r,a1,b1,a<<1|1));
    return mx;
}
int k;
bool chick(int a)
{
    int l=0;
    int cnt=0;
    if(a==0)
        return 0;

    while(l<=len)
    {
        int r=min(l+a-1,len);
        int ind=Ques(0,len,l,r,1);
       // printf("%d\n",ind);
        if(ind==-1)
            return 0;
        l=ind+1;
        cnt++;
    }
    if(cnt<=k)
        return 1;
    return 0;
}
int main()
{
    scanf("%d",&k);
    getchar();
    gets(z);
    len=strlen(z);
    len--;
    Build(0,len,1);
    int ans=inf;
    int l=0,r=inf;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(chick(mid))
        {
             r=mid-1;
             ans=min(mid,ans);
        }
        else
            l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}
View Code

 

codeforces 803