CSP-201604

问题描述

试题编号: 201604-1
试题名称:

折点计数

时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
  给定n个整数表示一个商店连续n天的销售量。如果某天之前销售量在增长,而后一天销售量减少,则称这一天为折点,反过来如果之前销售量减少而后一天销售量增长,也称这一天为折点。其他的天都不是折点。如下图中,第3天和第6天是折点。

  给定n个整数a1a2, …, an表示销售量,请计算出这些天总共有多少个折点。
  为了减少歧义,我们给定的数据保证:在这n天中相邻两天的销售量总是不同的,即ai-1ai。注意,如果两天不相邻,销售量可能相同。
输入格式
  输入的第一行包含一个整数n
  第二行包含n个整数,用空格分隔,分别表示a1a2, …, an
输出格式
  输出一个整数,表示折点出现的数量。
样例输入
7
5 4 1 2 3 6 4
样例输出
2
评测用例规模与约定
  所有评测用例满足:1 ≤ n ≤ 1000,每天的销售量是不超过10000的非负整数。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int n,a[1010],ans=0;
 5     cin>>n;
 6     for(int i=1;i<=n;++i){
 7         cin>>a[i];
 8     }for(int i=2;i<=n-1;++i){
 9         if(a[i-1]<a[i] && a[i]>a[i+1])ans++;
10         else if(a[i-1]>a[i] && a[i+1]>a[i])ans++;
11     }cout<<ans<<endl;
12     return 0;
13 }
View Code

问题描述

试题编号: 201604-2
试题名称:

俄罗斯方块

时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
  俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏。
  游戏在一个15行10列的方格图上进行,方格图上的每一个格子可能已经放置了方块,或者没有放置方块。每一轮,都会有一个新的由4个小方块组成的板块从方格图的上方落下,玩家可以操作板块左右移动放到合适的位置,当板块中某一个方块的下边缘与方格图上的方块上边缘重合或者达到下边界时,板块不再移动,如果此时方格图的某一行全放满了方块,则该行被消除并得分。
  在这个问题中,你需要写一个程序来模拟板块下落,你不需要处理玩家的操作,也不需要处理消行和得分。
  具体的,给定一个初始的方格图,以及一个板块的形状和它下落的初始位置,你要给出最终的方格图。
输入格式
  输入的前15行包含初始的方格图,每行包含10个数字,相邻的数字用空格分隔。如果一个数字是0,表示对应的方格中没有方块,如果数字是1,则表示初始的时候有方块。输入保证前4行中的数字都是0。
  输入的第16至第19行包含新加入的板块的形状,每行包含4个数字,组成了板块图案,同样0表示没方块,1表示有方块。输入保证板块的图案中正好包含4个方块,且4个方块是连在一起的(准确的说,4个方块是四连通的,即给定的板块是俄罗斯方块的标准板块)。
  第20行包含一个1到7之间的整数,表示板块图案最左边开始的时候是在方格图的哪一列中。注意,这里的板块图案指的是16至19行所输入的板块图案,如果板块图案的最左边一列全是0,则它的左边和实际所表示的板块的左边是不一致的(见样例)
输出格式
  输出15行,每行10个数字,相邻的数字之间用一个空格分隔,表示板块下落后的方格图。注意,你不需要处理最终的消行。
样例输入
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 0 0 0 1 1 1 1
0 0 0 0 1 0 0 0 0 0
0 0 0 0
0 1 1 1
0 0 0 1
0 0 0 0
3
样例输出
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 1 1 1 1 1 1 1
0 0 0 0 1 1 0 0 0 0

枚举最后一个有效行得位置,然后判断是否可行放置并更新行数h,最后根据h得知应放置在h行处。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int e[20][20];
 4 int b[5][5];
 5 int k;
 6 int main(){
 7     for(int i=1;i<=15;++i)
 8         for(int j=1;j<=10;++j)cin>>e[i][j];
 9     int st=999,ed=0;
10     for(int i=1;i<=4;++i){
11         int c=0;
12         for(int j=1;j<=4;++j){
13             cin>>b[i][j];
14             c|=b[i][j];
15         }
16         if(c) st=min(st,i),ed=max(ed,i);
17     }cin>>k;
18     int h;
19     for(int i=ed-st+1;i<=15;++i){
20         int x1,y1,x2,y2,ok=1;
21         for(x1=st,x2=i-(ed-st);x1<=ed && ok ;++x1,++x2){
22             for(y1=1,y2=k;y1<=4;++y1,++y2){
23                 if(b[x1][y1]==1&&e[x2][y2]==1){
24                     ok=0;
25                     break;
26                 }
27             }
28         }
29         if(ok)h=i;
30         else break;
31         }
32 
33     for(int x1=st,x2=h-(ed-st);x1<=ed ;++x1,++x2)
34     for(int y1=1,y2=k;y1<=4;++y1,++y2) e[x2][y2]^=b[x1][y1];
35     for(int i=1;i<=15;++i)
36     for(int j=1;j<=10;++j)printf("%d%c",e[i][j],j==10?'
':' ');
37     return 0;
38 }
View Code

问题描述

试题编号: 201604-4
试题名称:

游戏

时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
  小明在玩一个电脑游戏,游戏在一个n×m的方格图上进行,小明控制的角色开始的时候站在第一行第一列,目标是前往第n行第m列。
  方格图上有一些方格是始终安全的,有一些在一段时间是危险的,如果小明控制的角色到达一个方格的时候方格是危险的,则小明输掉了游戏,如果小明的角色到达了第n行第m列,则小明过关。第一行第一列和第n行第m列永远都是安全的。
  每个单位时间,小明的角色必须向上下左右四个方向相邻的方格中的一个移动一格。
  经过很多次尝试,小明掌握了方格图的安全和危险的规律:每一个方格出现危险的时间一定是连续的。并且,小明还掌握了每个方格在哪段时间是危险的。
  现在,小明想知道,自己最快经过几个时间单位可以达到第n行第m列过关。
输入格式
  输入的第一行包含三个整数nmt,用一个空格分隔,表示方格图的行数n、列数m,以及方格图中有危险的方格数量。
  接下来t行,每行4个整数rcab,表示第r行第c列的方格在第a个时刻到第b个时刻之间是危险的,包括ab。游戏开始时的时刻为0。输入数据保证rc不同时为1,而且当rnc不为m。一个方格只有一段时间是危险的(或者说不会出现两行拥有相同的rc)。
输出格式
  输出一个整数,表示小明最快经过几个时间单位可以过关。输入数据保证小明一定可以过关。
样例输入
3 3 3
2 1 1 1
1 3 2 10
2 2 2 10
样例输出
6
样例说明
  第2行第1列时刻1是危险的,因此第一步必须走到第1行第2列。
  第二步可以走到第1行第1列,第三步走到第2行第1列,后面经过第3行第1列、第3行第2列到达第3行第3列。
评测用例规模与约定
  前30%的评测用例满足:0 < nm ≤ 10,0 ≤ t < 99。
  所有评测用例满足:0 < nm ≤ 100,0 ≤ t < 9999,1 ≤ r ≤ n,1 ≤ c ≤ m,0 ≤ a ≤ b ≤ 100。

直接dp,由于a,b最大才100,所以最迟100时间之后所有的方格都是安全的,那么答案最大也就是300左右。

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 #define inf 0x3f3f3f3f
 5 
 6 int n,m,t;
 7 int a[105][105],b[105][105];
 8 bool f[315][105][105];
 9 int fx[4][2]={
10     1,0,
11     -1,0,
12     0,1,
13     0,-1
14 };
15 int main()
16 {
17     int r,c,aa,bb;
18     cin>>n>>m>>t;
19     for(int i=1;i<=t;++i){
20         cin>>r>>c>>aa>>bb;
21         a[r][c]=aa;
22         b[r][c]=bb;
23     }
24     f[0][1][1]=1;
25     for(int i=0;i<305;++i){
26         for(int x=1;x<=n;++x){
27             for(int y=1;y<=m;++y){
28                 if(!f[i][x][y])continue;
29                 for(int j=0;j<4;++j){
30                     int dx=x+fx[j][0];
31                     int dy=y+fx[j][1];
32                     if(dx<1||dy<1||dx>n||dy>m||(i+1>=a[dx][dy]&&i+1<=b[dx][dy]))continue;
33                     f[i+1][dx][dy]|=1;
34                 }
35             }
36         }
37         if(f[i][n][m]){
38             cout<<i<<endl;
39             return 0;
40         }
41     }
42     return 0;
43 }
View Code

-

原文地址:https://www.cnblogs.com/zzqc/p/12175112.html