题意
有一个n*m的图,一些单元格的底部有可以站立的平面,最下面一行都有
如果两个单元都包含平台并且| i1-i2 |,则Manao可以在两个单元(i1,j)和(i2,j)之间爬行
只有一个单元格包含金币
找到最短的梯子使得可以取到金币
#include
using namespace std;
int a[100][100],d[100][100],n,m;
queue< pair<int,int> > q;
class ArcadeManao {
public:
int shortestLadder( vector <string> level, int coinRow, int coinColumn ) ;
};
bool check(int x,int y)
{
return x>=1&&y>=1&&x<=n&&y<=m&&a[x][y]&&!d[x][y];
}
void sol(int u)
{
memset(d,0,sizeof(d));
q.push(make_pair(n,1));
d[n][1]=1;
int x,y,i;
while(!q.empty())
{
pair<int,int>w;
w=q.front();
q.pop();
x=w.first;
y=w.second;
if(check(x,y-1)) q.push(make_pair(x,y-1)),d[x][y-1]=1;
if(check(x,y+1)) q.push(make_pair(x,y+1)),d[x][y+1]=1;
for(i=-u;i<=u;i++)
if(check(x+i,y))
q.push(make_pair(x+i,y)),d[x+i][y]=1;
}
}
int ArcadeManao::shortestLadder(vector <string> s, int sx, int sy) {
int j,l,r,mid,i;
n=s.size();
m=s[0].size();
l=0;
r=n;
memset(a,0,sizeof(a));
for(i=0;i<n;i++)
for(j=0;j<m;j++)
if(s[i][j]=='X') a[i+1][j+1]=1;
while(l<r)
{
mid=(l+r)>>1;
sol(mid);
if(d[sx][sy]) r=mid;
else l=mid+1;
}
return l;
}
题意
房间的天花板上有N个落差计数器。 跌落计数器0与房间左端相距0.5厘米,下一个附着在前一个的右边1厘米处。
M个海绵放在房间里,长度都是L厘米,
实验要求海绵的附着方式是每分钟吸收[a,b]滴。
问 有多少种方法可以做到这一点
#include
using namespace std;
const int mod=1e9+9;
int a[1000],s[1000],d[510][510],g[510][510],h[510][510];
class TheExperiment {
public:
int countPlacements( vector <string> intensity, int M, int L, int A, int B ) ;
};
int TheExperiment::countPlacements(vector <string> in, int m, int len, int l, int r) {
int i,j,n=0,k;
for(i=0;i<in.size();i++)
for(j=0;j<in[i].size();j++)
a[++n]=in[i][j]-'0';
s[0]=0;
for(i=1;i<=n;i++)
s[i]=s[i-1]+a[i];
memset(h,0,sizeof(h));
h[0][0]=1;
for(i=1;i<=n;i++)
{
h[i][0]=1;
for(j=1;j<=m;j++)
{
for(k=1;k<len;k++)
if(i>=k&&l<=s[i]-s[i-k]&&s[i]-s[i-k]<=r)
d[i][j]=((d[i][j]+d[i-k][j-1])%mod+h[i-k][j-1])%mod;
for(k=1;k<=len;k++)
if(i>=k&&l<=s[i]-s[i-k]&&s[i]-s[i-k]<=r)
g[i][j]=(g[i][j]+g[i-k][j-1])%mod;
if(i>=len&&l<=s[i]-s[i-len]&&s[i]-s[i-len]<=r)
g[i][j]=((g[i][j]+d[i-len][j-1])%mod+h[i-len][j-1])%mod;
h[i][j]=(g[i-1][j]+h[i-1][j])%mod;
}
}
return (g[n][m]+h[n][m])%mod;
}
题意
Manao有一个矩阵X,有10,000行和W列。
他选择一个由最多W个小写字母组成的字符串S
cur := 0
for i := 0 to 9999
for j := 0 to W - 1
X[i][j] := S.charAt(cur)
cur := (cur + 1) mod length(S)
用这个来填充这个矩阵
计算Manao可以使用多少个不同的生成器来创建包含您给出的片段的矩阵X
#include
using namespace std;
const int mod=1e9+9;
long long d[1010][1010];
class CharacterBoard2 {
public:
int countGenerators( vector <string> fragment, int W, int i0, int j0 ) ;
};
int sol(int a,int y)
{
long long w=1,x=a;
while(y>0)
{
if(y&1) w=(w*x)%mod;
x=(x*x)%mod;
y=y>>1;
}
return (int)w;
}
int CharacterBoard2::countGenerators(vector <string> a, int w, int i0, int j0) {
long long ans=0;
int n,m,i,j,k,x,cnt,temp;
string s;
n=a.size();
m=a[0].size();
for(i=0;i<n;i++)
for(j=0;j<m;j++)
d[i][j]=((i+i0)*w+(j+j0))%mod;
for(k=1;k<=w;k++)
{
s.assign(k,'#');
x=1;
cnt=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
temp=d[i][j]%k;
if(s[temp]=='#')
{
s[temp]=a[i][j];
cnt++;
}
else if(s[temp]!=a[i][j])
{
x=0;
break;
}
}
if(x==0) break;
}
if(x==0) continue;
ans=(ans+sol(26,k-cnt))%mod;
}
return static_cast<int> (ans);
}