2012
2012
2012 特长生
目录:
A.安全密码
B.农场主
C.营救
D.栅栏的木料
A . A. A.安全密码
分析:
直接循环 × × ×
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define reg register
using namespace std;
typedef long long ll;
ll a,b,c,ans=1,T;
int main(){
freopen("password.in","r",stdin);
freopen("password.out","w",stdout);
scanf("%d%d%d",&a,&b,&c);
T=b;
while(T--) (ans*=a)%=c;
printf("%lld",ans);
return 0;
}
B . B. B.农场主
分析:
d
p
dp
dp
设
f
i
,
j
f_{i,j}
fi,j表示建了
i
i
i个马房 分配了前
j
j
j只马的最小系数
那么就可以再枚举一个
k
k
k
k
<
=
i
_{k<=i}
k<=i
f
i
,
j
=
m
i
n
{
f
i
,
j
,
f
i
−
1
,
k
+
s
u
m
k
,
j
}
f_{i,j}=min\{f_{i,j},f_{i-1,k}+sum_{k,j}\}
fi,j=min{fi,j,fi−1,k+sumk,j}
s
u
m
k
,
j
sum_{k,j}
sumk,j就是
k
,
j
k,j
k,j马房间系数的和
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define reg register
using namespace std;
typedef long long ll;
const int N=505;
int n,k,a[N],qwq[N],awa[N],ans,sum[N][N],f[N][N];
int main(){
freopen("farmer.in","r",stdin);
freopen("farmer.out","w",stdout);
memset(f,0x3f,sizeof f);
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
(a[i])?qwq[i]=1:awa[i]=1;
qwq[i]+=qwq[i-1];
awa[i]+=awa[i-1];
}
for(int i=1;i<=n;i++)
f[1][i]=qwq[i]*awa[i];
for(reg int i=1;i<=n;i++)
for(reg int j=1;j<=n;j++)
sum[i][j]=(qwq[i]-qwq[j])*(awa[i]-awa[j]);
for(reg int l=2;l<=k;l++)
for(reg int i=l+1;i<=n;i++)
for(reg int j=1;j<=i;j++)
f[l][i]=min(f[l][i],f[l-1][j]+sum[i][j]);
printf("%d",f[k][n]);
return 0;
}
C . C. C.营救
分析:
b f s bfs bfs
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define reg register
using namespace std;
typedef long long ll;
const int N=1005;
int n,dx[6]={0,1,0,-1},dy[6]={-1,0,1,0},vis[N][N],sx,sy,ex,ey;
char a[N][N];
struct node{
int x,y,step;
};
queue<node> q;
int bfs(int sx,int sy)
{
q.push((node){sx,sy,0});
while(!q.empty())
{
node x=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int xx=x.x+dx[i],yy=x.y+dy[i];
if(xx==ex&&yy==ey) return x.step+1;
if(xx<1||xx>n||yy<1||yy>n||a[xx][yy]=='1'||vis[xx][yy]) continue;
vis[xx][yy]=1;
q.push((node){xx,yy,x.step+1});
}
}
}
int main(){
freopen("save.in","r",stdin);
freopen("save.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
printf("%d",bfs(sx,sy));
return 0;
}
D . D. D.栅栏的木料
分析:
暴搜和剪枝
+
+
+ 二分答案
一个很显然的贪心思路就是用大木板去切小木料 以此基础暴搜
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define reg register
using namespace std;
typedef long long ll;
const int N=55;
int n,m,a[N],b[1055],ans,vis[N],sum[N],sum2[1055],tot,tmp,k[N];
bool dfs(int x,int last)
{
if(x==0) return 1;
if(b[x]^b[x+1])
last=tot;
for(int i=last;i<=n;i++)
if(!vis[i]&&k[i]>=b[x])
{
k[i]-=b[x];
if(k[i]<b[tot])
{
if(tmp<k[i])
{
k[i]+=b[x];
continue;
}
tmp-=k[i];
vis[i]=1;
if(dfs(x-1,i)) return 1;
tmp+=k[i];
vis[i]=0;
}
else
if(dfs(x-1,i)) return 1;
k[i]+=b[x];
}
return 0;
}
bool check(int x)
{
if(sum[n]<sum2[x]) return 0;
tmp=sum[n]-sum2[x];
tot=1;
while(a[tot]<b[1]&&tot<=n)
{
tmp-=a[tot];
if(tmp<0) return 0;
tot++;
}
for(int i=1;i<=n;i++) k[i]=a[i];
memset(vis,0,sizeof vis);
return dfs(x,1);
}
int main(){
freopen("fence.in","r",stdin);
freopen("fence.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i];
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d",&b[i]);
sort(b+1,b+m+1);
for(int i=1;i<=m;i++)
sum2[i]=sum2[i-1]+b[i];
int l=1,r=m;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))
{
ans=mid;
l=mid+1;
}
else r=mid-1;
}
printf("%d",ans);
return 0;
}