A - 验证栈序列
Description
给出两个序列 pushed 和 poped 两个序列,其取值从 1 到n(n≤100000)。已知入栈序列是 pushed,如果出栈序列有可能是 poped,则输出 Yes
,否则输出 No
。为了防止骗分,每个测试点有多组数据,不超过 5 组。
Input
第一行一个整数 q,询问次数。
接下来 q 个询问,对于每个询问:
第一行一个整数 nn 表示序列长度;
第二行 n 个整数表示入栈序列;
第三行 n 个整数表示出栈序列;
Output
对于每个询问输出答案。
Sample
Inputcopy | Outputcopy |
---|---|
2 5 1 2 3 4 5 5 4 3 2 1 4 1 2 3 4 2 4 1 3 | Yes No |
代码
#include<stdio.h>
#include<string.h>
int as(int a[],int b[],int n)
{
int c[100005]={0},*p=a,*q=b,tail=0,m=2*n;
while(m--)
{
if(tail-1<0||c[tail]!=*q){
c[++tail]=*p++;
}
else q++,tail--;
}
return tail==0;
}
int main()
{
int a;
scanf("%d",&a);
for(int i=0;i<a;i++)
{
int b,c[100005],d[100005];
scanf("%d",&b);
for(int i=0;i<b;i++)scanf("%d",&c[i]);
for(int i=0;i<b;i++)scanf("%d",&d[i]);
if(as(c,d,b))printf("Yes\n");
else printf("No\n");
}
return 0;
}
P - 奇怪的电梯
Description
呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 i 层楼(1≤i≤N)上有一个数字 Ki(0≤Ki≤N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如: 3,3,1,2,5 代表了 Ki(K1=3,K2=3,……),从 1 楼开始。在 1 楼,按“上”可以到 4 楼,按“下”是不起作用的,因为没有 −2 楼。那么,从 A 楼到 B 楼至少要按几次按钮呢?
Input
共二行。
第一行为三个用空格隔开的正整数,表示 N,A,B(1≤N≤200,1≤A,B≤N)。
第二行为 N 个用空格隔开的非负整数,表示 Ki。
Output
一行,即最少按键次数,若无法到达,则输出 -1
。
Sample
Inputcopy | Outputcopy |
---|---|
5 1 5 3 3 1 2 5 | 3 |
Hint
对于 100% 的数据,1≤N≤200,1≤A,B≤N,0≤Ki≤N。
本题共 16 个测试点,前 15 个每个测试点 6 分,最后一个测试点 10 分。
代码
广度算法:
#include<stdio.h>
#include<string.h>
struct Node{
int floor;
}node[205];
int main()
{
int floor_num,start_floor,end_floor,mark[205]={0},change_floor[205];
scanf("%d %d %d",&floor_num,&start_floor,&end_floor);
for(int i=1;i<=floor_num;i++)
{
scanf("%d",&change_floor[i]);
}
if(start_floor==end_floor){
printf("0");
return 0;
}
int head=1,tail=2,num=0,step[2]={1,-1};
node[head].floor=start_floor,mark[start_floor]=1;
while(head<tail)
{
int floor_temp,size=tail-head;
num++;
for(int j=0;j<size;j++)
{
for(int i=0;i<2;i++)
{
floor_temp=node[head].floor+step[i]*change_floor[node[head].floor];
if(floor_temp==end_floor){
printf("%d",num);
return 0;
}
if(floor_temp<1||floor_temp>floor_num||mark[floor_temp]!=0)continue;
else {
node[tail].floor=floor_temp;
mark[floor_temp]=1;
tail++;
}
}
head++;
}
}
printf("-1");
return 0;
}
深度算法(部分正确):
#include<stdio.h>
#include<string.h>
int as(int a[],int b[],int A,int B,int N,int num,int sum)
{
if(sum==B)return num;
b[sum-1]=1;
int c=a[sum-1],x=999999,y=999999;
if(sum+c<=N){
if(b[sum+c-1]==0)x=as(a,b,A,B,N,num+1,sum+c);
}
if(sum-c>0){
if(b[sum-c-1]==0)y=as(a,b,A,B,N,num+1,sum-c);
}
return x>y?y:x;
}
int main()
{
int N,A,B,o=0;
scanf("%d%d%d",&N,&A,&B);
int a[N],b[N];
for(int i=0;i<N;i++)scanf("%d",&a[i]);
if(A==B){
printf("0");
return 0;
}
memset(b,0,sizeof(b));
o=as(a,b,A,B,N,0,A);
if(o!=999999)printf("%d",o);
else printf("-1");
return 0;
}
N - Oil Deposits
Description
The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.
GeoSurvComp地质调查公司负责探测地下石油储量。GeoSurvComp一次处理一个大的矩形土地区域,并创建一个网格,将土地划分为多个正方形地块。然后,它分别分析每个地块,使用传感设备来确定地块是否含有石油。含有石油的地块称为口袋。如果两个油囊相邻,则它们是同一个油存款的一部分。石油矿床可能相当大,可能包含许多口袋。你的工作是确定网格中包含多少不同的石油沉积物。
Input
The input file contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.
输入文件包含一个或多个网格。每个网格以包含m和n的行开始,m和n是网格中的行数和列数,由单个空格分隔。如果m = 0,则表示输入结束;否则,1< = m <= 100并且1< = n <= 100。接下来是m行,每行n个字符(不包括行尾字符)。每个字符对应一个图,并且是“”,表示没有油,或者是“@”,表示油袋。
Output
For each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.
对于每个网格,输出不同的石油储量的数量。如果两个不同的油囊在水平、垂直或对角方向上相邻,则它们是同一个油存款的一部分。一个油存款不会包含超过100个口袋。
Sample
Input 输入 | Output 输出 |
---|---|
1 1 | 0 |
代码
#include<stdio.h>
#include<string.h>
struct Node{
int x;
int y;
};
void bfs(char map[][100],int mark[][100],int a,int b,int start_x,int start_y)
{
struct Node node[10000];
memset(node,0,sizeof(node));
int head=0,tail=1,range[8][2]={
{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
node[0].x=start_x,node[0].y=start_y;
mark[start_x][start_y]=1,map[start_x][start_y]='\0';
while(head<tail)
{
int temp_x,temp_y;
for(int i=0;i<8;i++)
{
temp_x=node[head].x+range[i][0],temp_y=node[head].y+range[i][1];
if(temp_x>=a||temp_y>=b||temp_x<0||temp_y<0||mark[temp_x][temp_y]!=0)continue;
if(map[temp_x][temp_y]=='@'){
node[tail].x=temp_x,node[tail].y=temp_y;
map[temp_x][temp_y]='\0',mark[temp_x][temp_y]=1;
tail++;
}
}
head++;
}
}
int main()
{
int a,b;
while(1)
{
char map[100][100];
scanf("%d %d",&a,&b);
if(a==0)break;
int num=0,mark[100][100];
for(int i=0;i<a;i++)
{
scanf("%s",map[i]);
}
memset(mark,0,sizeof(mark));
for(int i=0;i<a;i++)
{
for(int j=0;j<b;j++)
{
if(map[i][j]=='@'&&mark[i][j]==0){
bfs(map,mark,a,b,i,j);
num++;
}
}
}
printf("%d\n",num);
}
return 0;
}
G - 自然数的拆分问题
Description
任何一个大于 1 的自然数 n,总可以拆分成若干个小于 n 的自然数之和。现在给你一个自然数 n,要求你求出 n 的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。
Input
输入:待拆分的自然数 n。
Output
输出:若干数的加法式子。
Sample
Inputcopy | Outputcopy |
---|---|
7 | 1+1+1+1+1+1+1 1+1+1+1+1+2 1+1+1+1+3 1+1+1+2+2 1+1+1+4 1+1+2+3 1+1+5 1+2+2+2 1+2+4 1+3+3 1+6 2+2+3 2+5 3+4 |
Hint
数据保证,2≤n≤8。
代码
#include<stdio.h>
int check(int a[],int n)
{
for(int i=0;i<n-1;i++)
{
if(a[i]>a[i+1])return 0;
}
return 1;
}
void dfs(int a,int b[],int c[][100],int n)
{
if(n==1)return ;
if(b[n-2]<=b[n-1]&&check(b,n)==1){
for(int i=0;i<n;i++)
{
if(i<n-1)printf("%d+",b[i]);
else printf("%d\n",b[i]);
}
}
if(n>=2){
if(b[n-1]<=2){
b[n-2]+=b[n-1],b[n-1]=0;
dfs(a,b,c,n-1);
}
else {
b[n-2]++,b[n-1]--;
while(b[n-1]>=4){
b[n]=b[n-1]-2,b[n-1]=2,n++;
}
dfs(a,b,c,n);
}
}
}
int main()
{
int a,b[100],c[100][100];
scanf("%d",&a);
for(int i=0;i<100;i++)b[i]=1;
dfs(a,b,c,a);
return 0;
}
声明:所用题皆来自刷题网,作者仅用来向组织反馈学习情况,无任何盈利行为。