成绩是国二中游,赛场上填空题写了第1,2,5题,第2题大意错了,编程题写了第7,8,10题,第7题对了样例,后两题不知道可以对多少,总分有50左右吧。
本题总分:5 分
【问题描述】
小蓝特别喜欢 2,今年是公元 2020 年,他特别高兴。
他很好奇,在公元 1 年到公元 2020 年(包含)中,有多少个年份的数位中包含数字 2?
签到题。答案563
#include
using namespace std;
int n,m,ans;
int main()
{
int i,j;
for(i=1;i<=2020;i++){
j=i;
while(j){
if(j%10==2){
ans++;
printf("%d ",i);
break;
}
j/=10;
}
}
printf("\n%d",ans);
return 0;
}
//563
本题总分:5 分
【问题描述】
小蓝在一张无限大的特殊画布上作画。
这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。
小蓝在画布上首先点了一下几个点:(0, 0), (2020, 11), (11, 14), (2000, 2000)。
只有这几个格子上有黑色,其它位置都是白色的。
每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色(如果原来就是黑色,则还是黑色)。
请问,经过 2020 分钟后,画布上有多少个格子是黑色的。
我的是bfs从四个点搜索的,看网上大部分的答案不是这个:11157392。
emmm和同学交流后发现还有可能有负数的情况,我大E了,没有闪。。
实现也不难吧,每个点的坐标加上2100,因为每次扩散1,向后扩散2020次,2100够用了,数组也扩大一点,然后扩散。这个答案是20312088
修改后的:
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
const int N=10000;
typedef long long ll;
int n,m;
ll ans;
bool a[N][N];
struct node{
int x,y,st;
}s,t;
int hy[4][2]={
1,0, -1,0, 0,1, 0,-1};
void bfs(){
int i;
queue<node>q;
q.push((node){
0+2100,0+2100,0});
q.push((node){
2020+2100,11+2100,0});
q.push((node){
11+2100,14+2100,0});
q.push((node){
2000+2100,2000+2100,0});
a[0+2100][0+2100]=a[2020+2100][11+2100]=a[11+2100][14+2100]=a[2000+2100][2000+2100]=1;
ans=4;
while(!q.empty()){
t=q.front();
q.pop();
s.st=t.st+1;
for(int i=0;i<4;i++){
s.x=t.x+hy[i][0];
s.y=t.y+hy[i][1];
if(s.x>=0&&s.y>=0&&a[s.x][s.y]==0&&s.st<=2020){
a[s.x][s.y]=1;
ans++;
q.push(s);
}
}
}
printf("%d",ans);
}
int main()
{
int i,j;
bfs();
return 0;
}
//20312088
本题总分:10 分
【问题描述】
定义阶乘 n! = 1 × 2 × 3 × · · · × n。
请问 100! (100 的阶乘)有多少个约数。
其实就是把从那些因子中挑出来问你最多能组成多少个数。
为了防止2* 3=6的重复计算,我们不能直接挑,所以要先用唯一分解定理分解成素因子乘积的形式
如:5!=1* 2* 3* 4* 5=2^3 +3^1 +5^1;
所以现在的情况变成了:2有4种选择(0、1、2、3个),3有2种选择(0、1个),5有2种选择(0、1个).即每个素因子的选择个数是其幂次+1。
所以对于100!的答案就是把2-100的每一个数进行分解,记录下每一个素因子的个数,然后+1乘起来即可
#include
using namespace std;
const int N=105;
typedef long long ll;
int a[N];
int main()
{
int i,j,k,x,y;
for(i=2;i<=100;i++){
x=i;
for(j=2;j*j<=i;j++){
while(x%j==0){
a[j]++;
x/=j;
}
}
if(x!=1) a[x]++;
}
ll ans=1;
for(i=1;i<=100;i++){
if(a[i]) ans*=(a[i]+1);
}
printf("%lld",ans);
return 0;
}
本题总分:10 分
【问题描述】
小蓝特别喜欢单调递增的事物。
在一个字符串中,如果取出若干个字符,将这些字符按照在字符串中的顺序排列后是单调递增的,则成为这个字符串中的一个单调递增子序列。
例如,在字符串 lanqiao 中,如果取出字符 n 和 q,则 nq 组成一个单调递增子序列。类似的单调递增子序列还有 lnq、i、ano 等等。
小蓝发现,有些子序列虽然位置不同,但是字符序列是一样的,例如取第二个字符和最后一个字符可以取到 ao,取最后两个字符也可以取到 ao。小蓝认为他们并没有本质不同。
对于一个字符串,小蓝想知道,本质不同的递增子序列有多少个?
例如,对于字符串 lanqiao,本质不同的递增子序列有 21 个。它们分别是 l、a、n、q、i、o、ln、an、lq、aq、nq、ai、lo、ao、no、io、lnq、anq、lno、ano、aio。
请问对于以下字符串(共 200 个小写英文字母,分四行显示):
tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhf
iadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqij
gihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmad
vrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define mk make_pair
const int inf=0x3f3f3f3f;
typedef long long ll;
int n,m,ans;
char s[500]="tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhfiadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqijgihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmadvrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl";
map<string,int>vis;
int main()
{
int i,j,k;
queue<pair<string,int> >q;
for(i=0;i<200;i++){
string str="";
str+=s[i];
if(vis[str]==0){
vis[str]=1;
q.push(mk(str,i));
ans++;
}
}
while(!q.empty()){
string str=q.front().first;
int pos=q.front().second;
q.pop();
for(i=pos+1;i<200;i++){
if(s[i]>s[pos]&&vis[str+s[i]]==0){
vis[str+s[i]]=1;
q.push(mk(str+s[i],i));
ans++;
}
}
}
printf("%d",ans);
return 0;
}
本题总分:15 分
【问题描述】
小蓝有一条玩具蛇,一共有 16 节,上面标着数字 1 至 16。每一节都是一个正方形的形状。相邻的两节可以成直线或者成 90 度角。小蓝还有一个 4 × 4 的方格盒子,用于存放玩具蛇,盒子的方格上依次标着字母 A 到 P 共 16 个字母。小蓝可以折叠自己的玩具蛇放到盒子里面。他发现,有很多种方案可以将玩具蛇放进去。
下图给出了两种方案:
请帮小蓝计算一下,总共有多少种不同的方案。如果两个方案中,存在玩
具蛇的某一节放在了盒子的不同格子里,则认为是不同的方案。
dfs四个方向搜索即可,答案552
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
int n=4,m,ans;
int v[5][5];
int hy[4][2]={
1,0, -1,0, 0,1, 0,-1};
void dfs(int x,int y,int sum){
// if(x<1||y<1||x>n||y>n) return ;
if(sum==n*n){
ans++;
return;
}
for(int i=0;i<4;i++){
int fx=x+hy[i][0];
int fy=y+hy[i][1];
if(fx<1||fy<1||fx>n||fy>n||v[fx][fy]==1) continue;
v[fx][fy]=1;
dfs(fx,fy,sum+1);
v[fx][fy]=0;
}
}
int main()
{
int i,j;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
memset(v,0,sizeof(v));
v[i][j]=1;
dfs(i,j,1);
}
}
printf("%d",ans);
return 0;
}
时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分
【问题描述】
皮亚诺曲线是一条平面内的曲线。
下图给出了皮亚诺曲线的 1 阶情形,它是从左下角出发,经过一个 3×3 的方格中的每一个格子,最终到达右上角的一条曲线。
下图给出了皮亚诺曲线的 2 阶情形,它是经过一个 3 2 × 3 2 的方格中的每一个格子的一条曲线。它是将 1 阶曲线的每个方格由 1 阶曲线替换而成。
下图给出了皮亚诺曲线的 3 阶情形,它是经过一个 3 3 × 3 3 的方格中的每一个格子的一条曲线。它是将 2 阶曲线的每个方格由 1 阶曲线替换而成。( 最后一列倒数六和第七个点应该连着,图片有误)
皮亚诺曲线总是从左下角开始出发,最终到达右上角。我们将这些格子放到坐标系中,对于 k 阶皮亚诺曲线,左下角的坐标是(0,0),右上角坐标是 (3 k − 1,3 k − 1),右下角坐标是 (3 k − 1,0),左上角坐标是(0,3 k − 1)。给定 k 阶皮亚诺曲线上的两个点的坐标,请问这两个点之间,如果沿着皮亚诺曲线走,距离是到少?
【输入格式】
输入的第一行包含一个正整数 k,皮亚诺曲线的阶数。
第二行包含两个整数 x 1 , y 1 ,表示第一个点的坐标。
第三行包含两个整数 x 2 , y 2 ,表示第二个点的坐标。
【输出格式】
输出一个整数,表示给定的两个点之间的距离。
【样例输入】
1
0 0
2 2
【样例输出】
8
【样例输入】
2
0 2
0 3
【样例输出】
13
【评测用例规模与约定】
对于 30% 的评测用例,0 ≤ k ≤ 10。
对于 50% 的评测用例,0 ≤ k ≤ 20。
对于所有评测用例,0 ≤ k ≤ 100, 0 ≤ x 1 ,y 1 , x 2 ,y 2 < 3 k , x 1 ,y 1 , x 2 ,y 2 ≤ 10 18 。
数据保证答案不超过 10 18 。
这次蓝桥不讲武德, 乱放题的顺序,不好写的放到前面了。还好赛场上我看了一下这题就跳过了。
时间限制: 1.0s
内存限制: 256.0MB
本题总分:20 分
【问题描述】
L 星球游乐园非常有趣,吸引着各个星球的游客前来游玩。小蓝是 L 星球游乐园的管理员。为了更好的管理游乐园,游乐园要求所有的游客提前预约,小蓝能看到系统上所有预约游客的名字。每个游客的名字由一个大写英文字母开始,后面跟0 个或多个小写英文字母。游客可能重名。小蓝特别喜欢递增的事物。今天,他决定在所有预约的游客中,选择一部分游客在上午游玩,其他的游客都在下午游玩,在上午游玩的游客要求按照预约的顺序排列后,名字是单调递增的,即排在前面的名字严格小于排在后面的名字。
一个名字 A 小于另一个名字 B 是指:存在一个整数 i,使得 A 的前 i 个字母与 B 的前 i 个字母相同,且 A 的第 i+1 个字母小于 B 的第 i+1 个字母。(如果 A 不存在第 i + 1 个字母且 B 存在第 i + 1 个字母,也视为 A 的第 i + 1 个字母小于 B 的第 i + 1 个字母)
作为小蓝的助手,你要按照小蓝的想法安排游客,同时你又希望上午有尽量多的游客游玩,请告诉小蓝让哪些游客上午游玩。如果方案有多种,请输出上午游玩的第一个游客名字最小的方案。如果此时还有多种方案,请输出第一个游客名字最小的前提下第二个游客名字最小的方案。如果仍然有多种,依此类推选择第三个、第四个……游客名字最小的方案。
【输入格式】
输入包含一个字符串,按预约的顺序给出所有游客的名字,相邻的游客名字之间没有字符分隔。
【输出格式】
按预约顺序输出上午游玩的游客名单,中间不加任何分隔字符。
【样例输入】
WoAiLanQiaoBei
【样例输出】
AiLanQiao
【评测用例规模与约定】
对于 20% 的评测数据,输入的总长度不超过 20 个字母。
对于 50% 的评测数据,输入的总长度不超过 300 个字母。
对于 70% 的评测数据,输入的总长度不超过 10000 个字母。
对于所有评测数据,每个名字的长度不超过 10 个字母,输入的总长度不超过 1000000 个字母。
先把名字处理保存一下,然后名字就按最长上升子序列来。
修正过的代码:每个名字都会在保存状态的b数组中出现,保存每个名字在b数组出现的位置,通过逆序检索,就可以求出原来的最长上升子序列。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
int n,m;
string s,a[100005],b[100005],c[100005];
int main()
{
int i,j,cnt=0;
cin>>s;
for(i=0;i<s.length();i++){
if(s[i]>='A'&&s[i]<='Z'){
a[++cnt]+=s[i];
i++;
while(s[i]>='a'&&s[i]<='z'){
a[cnt]+=s[i];
i++;
}
i--;
}
}
// for(i=1;i<=cnt;i++){ cout<
int sum=1;
int p[100005];
b[1]=a[1];
p[1]=sum;
for(i=2;i<=cnt;i++){
if(a[i]>b[sum]) {
b[++sum]=a[i];
p[i]=sum;
}
else{
m=lower_bound(b+1,b+1+sum,a[i])-b;
b[m]=a[i];
p[i]=m;
}
}
int temp=sum;
for(i=cnt;i>=1;i--){
if(temp==0) break;
if(p[i]==temp){
c[temp]=a[i];
temp--;
}
}
for(i=1;i<=sum;i++){
cout<<c[i];
}
return 0;
}
赛场代码,保存记录写错了,希望能多给几分吧。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
int n,m;
string s,a[1000005],b[1000005],c[1000005];
int main()
{
int i,j,cnt=0;
cin>>s;
for(i=0;i<s.length();i++){
if(s[i]>='A'&&s[i]<='Z'){
a[++cnt]+=s[i];
i++;
while(s[i]>='a'&&s[i]<='z'){
a[cnt]+=s[i];
i++;
}
i--;
}
}
// for(i=1;i<=cnt;i++){ cout<
int sum=1;
c[1]=b[1]=a[1];
for(i=2;i<=cnt;i++){
if(a[i]>b[sum]) {
c[++sum]=a[i];
b[++sum]=a[i];
}
else{
if(sum==1){
*lower_bound(c+1,c+1+sum,a[i])=a[i];
}
*lower_bound(b+1,b+1+sum,a[i])=a[i];
}
}
for(i=1;i<=sum;i++){
cout<<c[i];
}
return 0;
}
时间限制: 1.0s
内存限制: 256.0MB
本题总分:20 分
【问题描述】
有 n 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。老师可以安排答疑的顺序,同学们要依次进入老师办公室答疑。
一位同学答疑的过程如下:
3
10000 10000 10000
20000 50000 20000
30000 20000 30000
【样例输出】
280000
【样例说明】
按照 1, 3, 2 的顺序答疑,发消息的时间分别是 20000, 80000, 180000。
【评测用例规模与约定】
对于 30% 的评测用例,1 ≤ n ≤ 20。
对于 60% 的评测用例,1 ≤ n ≤ 200。
对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ si ≤ 60000,1 ≤ ai ≤ 1000000,
ei ∈ {10000, 20000, 30000},即 ei 一定是 10000、20000、30000 之一。
贪心?我是排个序,先按每个人需要的总时间排,因为后面的人总是等着前面的人,相同的话对前两项数据和排,可以是答案尽可能小。
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
int n,m;
ll ans=0,sum=0;
struct node{
int z,s1,s2;
}s[1000];
int cmp(node a,node b){
if(a.s2!=b.s2) return a.s2<b.s2;
else return a.s1<b.s1;
}
int main()
{
int i,j,x,y,z;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d %d %d",&x,&y,&s[i].z);
s[i].s1=x+y;
s[i].s2=x+y+s[i].z;
}
sort(s,s+n,cmp);
for(i=0;i<n;i++){
ans+=s[i].s1;
sum+=ans;
ans+=s[i].z;
}
printf("%lld",sum);
return 0;
}
时间限制: 1.0s
内存限制: 256.0MB
本题总分:25 分
【问题描述】
小蓝在 L 市开出租车。
L 市的规划很规整,所有的路都是正东西向或者正南北向的,道路都可以看成直线段。东西向的道路互相平行,南北向的道路互相平行,任何一条东西向道路垂直于任何一条南北向道路。
从北到南一共有 n 条东西向道路,依次标号为 H1, H2, · · · , Hn。从西到东一共有 m 条南北向的道路,依次标号为 S 1, S 2, · · · , S m。
每条道路都有足够长,每一条东西向道路和每一条南北向道路都相交,Hi与 S j 的交叉路口记为 (i, j)。
从 H1 和 S 1 的交叉路口 (1, 1) 开始,向南遇到的路口与 (1, 1) 的距离分别是 h1, h2, · · · , hn−1,向东遇到路口与 (1, 1) 的距离分别是 w1, w2, · · · , wm−1。
道路的每个路口都有一个红绿灯。
时刻 0 的时候,南北向绿灯亮,东西向红灯亮,南北向的绿灯会持续一段时间(每个路口不同),然后南北向变成红灯,东西向变成绿灯,持续一段时间后,再变成南北向绿灯,东西向红灯。
已知路口 (i, j) 的南北向绿灯每次持续的时间为 gij,东西向的绿灯每次持续的时间为 ri j,红绿灯的变换时间忽略。
当一辆车走到路口时,如果是绿灯,可以直行、左转或右转。如果是红灯,可以右转,不能直行或左转。如果到路口的时候刚好由红灯变为绿灯,则视为看到绿灯,如果刚好由绿灯变为红灯,则视为看到红灯。
每段道路都是双向道路,道路中间有隔离栏杆,在道路中间不能掉头,只能在红绿灯路口掉头。掉头时不管是红灯还是绿灯都可以直接掉头。掉头的时间可以忽略。
小蓝时刻 0 从家出发。今天,他接到了 q 个预约的订单,他打算按照订单的顺序依次完成这些订单,就回家休息。中途小蓝不准备再拉其他乘客。
小蓝的家在两个路口的中点,小蓝喜欢用 x1, y1, x2, y2 来表示自己家的位置,即路口 (x1, y1) 到路口 (x2, y2) 之间的道路中点的右侧,保证两个路口相邻(中间没有其他路口)。请注意当两个路口交换位置时,表达的是路的不同两边,路中间有栏杆,因此这两个位置实际要走比较远才能到达。小蓝的订单也是从某两个路口间的中点出发,到某两个路口间的中点结束。小蓝必须按照给定的顺序处理订单,而且一个时刻只能处理一个订单,不能图省时间而同时接两位乘客,也不能插队完成后面的订单。小蓝只对 L 市比较熟,因此他只会在给定的 n 条东西向道路和 m 条南北向道路上行驶,而且不会驶出 H1, Hn, S 1, S m 这几条道路所确定的矩形区域(可以到边界)。小蓝行车速度一直为 1,乘客上下车的时间忽略不计。
请问,小蓝最早什么时候能完成所有订单回到家。
【输入格式】
输入第一行包含两个整数 n, m,表示东西向道路的数量和南北向道路的数
量。
第二行包含 n − 1 个整数 h1, h2, · · · , hn−1。
第三行包含 m − 1 个整数 w1, w2, · · · , wm−1。
接下来 n 行,每行 m 个整数,描述每个路口南北向绿灯的时间,其中的第
i 行第 j 列表示 gi j。
接下来 n 行,每行 m 个整数,描述每个路口东西向绿灯的时间,其中的第
i 行第 j 列表示 ri j。
接下来一行包含四个整数 x1, y1, x2, y2,表示小蓝家的位置在路口 (x1, y1)
到路口 (x2, y2) 之间的道路中点的右侧。
接下来一行包含一个整数 q,表示订单数量。
接下来 q 行,每行描述一个订单,其中第 i 行包含八个整数 xi1, yi1, xi2, yi2,
xi3, yi3, xi4, yi4,表示第 i 个订单的起点为路口 (xi1, yi1) 到路口 (xi2, yi2) 之间的道
路中点的右侧,第 i 个订单的终点为路口 (xi3, yi3) 到路口 (xi4, yi4) 之间的道路中
点的右侧。
【输出格式】
输出一个实数,表示小蓝完成所有订单最后回到家的最早时刻。四舍五入
保留一位小数。
【样例输入】
2 3
200
100 400
10 20 10
20 40 30
20 20 20
20 20 20
2 1 1 1
1
2 2 1 2 1 2 1 3
【样例输出】
1620.0
【样例说明】
小蓝有一个订单,他的行车路线如下图所示。其中 H 表示他家的位置,S
表示订单的起点,T 表示订单的终点。小明在最后回家时要在直行的红绿灯路
口等绿灯,等待时间为 20。
【评测用例规模与约定】
对于 20% 的评测用例,1 ≤ n, m ≤ 5,1 ≤ q ≤ 10。
对于 50% 的评测用例,1 ≤ n, m ≤ 30,1 ≤ q ≤ 30。
对于所有评测用例,1 ≤ n, m ≤ 100,1 ≤ q ≤ 30,1 ≤ h1 < h2 < · · · < hn−1 ≤
100000,1 ≤ w1 < w2 < · · · < wm−1 ≤ 100000,1 ≤ gij ≤ 1000,1 ≤ rij ≤ 1000,给
定的路口一定合法。
题面太长不想看。。
时间限制: 1.0s
内存限制: 256.0MB
本题总分:25 分
【问题描述】
小蓝在玩一个叫质数行者的游戏。
游戏在一个 n × m × w 的立体方格图上进行,从北到南依次标号为第 1 行到第 n 行,从西到东依次标号为第 1 列到第 m 列,从下到上依次标号为第 1 层到第 w 层。
小蓝要控制自己的角色从第 1 行第 1 列第 1 层移动到第 n 行第 m 列第 w层。每一步,他可以向东走质数格、向南走质数格或者向上走质数格。每走到一个位置,小蓝的角色要稍作停留。
在游戏中有两个陷阱,分别为第 r1 行第 c1 列第 h1 层和第 r2 行第 c2 列第h2 层。这两个陷阱的位置可以跨过,但不能停留。也就是说,小蓝不能控制角色某一步正好走到陷阱上,但是某一步中间跨过了陷阱是允许的。
小蓝最近比较清闲,因此他想用不同的走法来完成这个游戏。所谓两个走法不同,是指小蓝稍作停留的位置集合不同。
请帮小蓝计算一下,他总共有多少种不同的走法。
提示:请注意内存限制,如果你的程序运行时超过内存限制将不得分。
【输入格式】
输入第一行包含两个整数 n, m, w,表示方格图的大小。
第二行包含 6 个整数,r1, c1, h1, r2, c2, h2,表示陷阱的位置。
【输出格式】
输出一行,包含一个整数,表示走法的数量。答案可能非常大,请输出答案除以 1000000007 的余数。
【样例输入】
5 6 1
3 4 1 1 2 1
【样例输出】
11
【样例说明】 用 (r, c, h) 表示第 r 行第 c 列第 h 层,可能的走法有以下几种:
- (1, 1, 1) − (1, 3, 1) − (1, 6, 1) − (3, 6, 1) − (5, 6, 1)。
- (1, 1, 1) − (1, 3, 1) − (3, 3, 1) − (3, 6, 1) − (5, 6, 1)。
- (1, 1, 1) − (1, 3, 1) − (3, 3, 1) − (5, 3, 1) − (5, 6, 1)。
- (1, 1, 1) − (3, 1, 1) − (3, 3, 1) − (3, 6, 1) − (5, 6, 1)。
- (1, 1, 1) − (3, 1, 1) − (3, 3, 1) − (5, 3, 1) − (5, 6, 1)。
- (1, 1, 1) − (3, 1, 1) − (5, 1, 1) − (5, 3, 1) − (5, 6, 1)。
- (1, 1, 1) − (3, 1, 1) − (5, 1, 1) − (5, 4, 1) − (5, 6, 1)。
- (1, 1, 1) − (1, 4, 1) − (1, 6, 1) − (3, 6, 1) − (5, 6, 1)。
- (1, 1, 1) − (1, 6, 1) − (3, 6, 1) − (5, 6, 1)。
- (1, 1, 1) − (3, 1, 1) − (3, 6, 1) − (5, 6, 1)。
- (1, 1, 1) − (3, 1, 1) − (5, 1, 1) − (5, 6, 1)。
【评测用例规模与约定】
对于 30% 的评测用例 1 ≤ n, m, w ≤ 50。
对于 60% 的评测用例 1 ≤ n, m, w ≤ 300。
对于所有评测用例,1 ≤ n, m, w ≤ 1000,1 ≤ r1, r2 ≤ n, 1 ≤ c1, c2 ≤ m,1 ≤ h1, h2 ≤ w,陷阱不在起点或终点,两个陷阱不同。
记忆化搜索,有两个点不能走。写完代码样例一遍过,就是记录数据的三维数组不敢开到1000,只敢开到300,有一点分吧。
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1005;
typedef long long ll;
int n,m,w,ans,f1,f2,f3,w1,w2,w3,cnt;
int a[N],p[N];
int f[305][305][305];
int judge(int x,int y,int z){
if(x==f1&&y==f2&&z==f3) return 0;
if(x==w1&&y==w2&&z==w3) return 0;
return 1;
}
int dfs(int x,int y,int z,int sum){
if(x==n&&y==m&&z==w) return 1;
if(f[x][y][z]!=-1) return f[x][y][z];
int c=0;
for(int i=0;i<cnt;i++){
if(x+p[i]<=n&&judge(x+p[i],y,z)){
c+=dfs(x+p[i],y,z,sum);
}
if(y+p[i]<=m&&judge(x,y+p[i],z)){
c+=dfs(x,y+p[i],z,sum);
}
if(z+p[i]<=w&&judge(x,y,z+p[i])){
c+=dfs(x,y,z+p[i],sum);
}
}
return f[x][y][z]=c;
}
int main()
{
int i,j;
scanf("%d %d %d",&n,&m,&w);
scanf("%d %d %d",&f1,&f2,&f3);
scanf("%d %d %d",&w1,&w2,&w3);
for(i=2;i<=N;i++){
if(a[i]==0){
p[cnt++]=i;
for(j=i+i;j<=N;j+=i){
a[j]=1;
}
}
}
memset(f,-1,sizeof(f));
dfs(1,1,1,0);
printf("%d",f[1][1][1]);
return 0;
}