A
半天没思路,弱死。。。后来做标记,发现标记序列必须是LLLLLRRRRR格式,第i个字母代表机器人拿第i个物品用哪只手,无论怎样,序列必须是左边若干个L和右边若干个R组成,且不可能是LLLRR..RRRLLL..LL,代码省略了
C
不会。。刚开始转换都没有想到 。。。。T T
题目转换一下,任意a[i] % d <= k, 求d得最大值
容易看出,dmax <= min{a},设min{a} = m
若m <= k+1
则 a[i] % m <k+1 <= k 正好符合要求
若 m>k+1
则在【k+1,m】穷举
TLE怎么办???!!!
用到分块的思想,记录cnt[x]代表数组中有多少个元素在1-x之间
对于某一个符合要求的d而言
区间 [1*d...1*d+k]U[2*d..2*d+k]U...U[(m/d)*d....(m/d)*d+k]这m/d个区间内总共覆盖数组所有值
复杂度O(m/d)
由于,m/1+m/2+...m/m~mlogm,即总复杂度O(mlogm)
附代码;
#include <iostream>
#include <cstdio>
#define N 1000005
using namespace std;
int cnt[N],a[N],n,k;
int answing(int d)
{
int i,zs=0,t;
for (i=1;i<=(N-1)/d;i++)
if (i==(N-1)/d)
{
t = min(N-1,i*d+k);
zs+=(cnt[t]-cnt[i*d-1]);
}
else
{
zs+=(cnt[i*d+k]-cnt[i*d-1]);
}
if (zs==n) return 1;
return 0;
}
int main()
{
int m=2*N,i;
cin>>n>>k;
for (i=1;i<=n;i++)
{
cin>>a[i];
cnt[a[i]]++;
if (a[i]<m) m = a[i];
}
if (m<=k+1)
cout<<m<<endl;
else
{
cnt[0] = 0;
for (i=1;i<N;i++) cnt[i] += cnt[i-1];
for (i=m;i>=k+1;i--)
if (answing(i))
{
cout<<i<<endl;
break;
}
}
return 0;
}
E
只想到了搜索,觉得超时,没敢想,发现有简单的DP算法。。。
刚开始初始化,把6个数看成1个数,而每个数的数位有若干种情况(比如21=7+7+7+0+。。+0) ,用vector保存,保存数值和表达方式
DP[I][J] 代表状态进位为j出现在第i位,并且后面i-1位全部与n的后i-1位对应 是如何得到的
DP[I+1][(J+U[K].VALUE)/10] = K,当且(j+u[k].value)%10=b[i]
其中b[i]代表数位,u代表之前的vector
最后反向递推即可,附代码:
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cstring>
#define cl(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define ll __int64
using namespace std;
struct inform
{
int value;
int c[6];
} ;
vector<inform>a;
int f[22][6],b[22],u[25];
ll p[6];
void print(int l)
{
int i,j;
ll bitnum=1;
cl(p,0);
for (i=1;i<=l;i++)
{
for (j=0;j<6;j++) p[j]+=a[u[i]].c[j]*bitnum;
bitnum*=10;
}
for (i=0;i<6;i++)
{
cout<<p[i];
if (i<5) cout<<" ";
else cout<<endl;
}
return;
}
void trying(int l)
{
int i,j,k;
cl(f,-1);
f[1][0]=0;
for (i=1;i<=l;i++)
for (j=0;j<=4;j++)
if (f[i][j]>-1)
{
for (k=0;k<a.size();k++)
if ((j+a[k].value)%10==b[i])
{
f[i+1][(j+a[k].value)/10] = k;
}
}
if (f[l+1][0]>-1)
{
cl(u,0);
j=0;
for (i=l;i>=1;i--)
{
u[i] = f[i+1][j];
j=j*10+b[i]-a[u[i]].value;
}
print(l);
return;
}
cout<<-1<<endl;
return;
}
void init()
{
int i,j,k;
for (i=0;i<=6;i++)
for (j=0;i+j<=6;j++)
{
inform nein;
nein.value=i*7+j*4;
for (k=0;k<6;k++)
{
if (k<i) nein.c[k]=7;
else if (k<i+j) nein.c[k]=4;
else nein.c[k]=0;
}
a.pb(nein);
}
}
int main()
{
init();
int t,l;
ll n;
cin>>t;
while (t--)
{
cin>>n;
cl(b,0);
l=0;
while (n>0)
{
b[++l]=n%10;
n/=10;
}
trying(l);
}
return 0;
}