1. 程式人生 > >codeforces 803

codeforces 803

其中 hid i+1 fab while sqrt queue printf 線段

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