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 "); else { 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; }
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 ",min(l[n],r[n])); } return 0; }
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 ",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 "); return 0; }
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 ",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 ",ans); return 0; }