2023/3/14总结

目录

CF-A题

CF-B题

作业A题

作业-C题

作业-D题

看《JAVA讲义》


Problem - A - Codeforces

CF-A题

1.这一题乍一看,像是用BFS,但是bfs很可能出错。还是要找到其中规律去写。

对于下面,我们知道他只能上下左右走,那么可以明白的是,最优是下面这个样子,但是它又规定不能连续俩次选择一种方案。

因此我们可以变成这个样子去走,也是最短的。

这个就简单咯,是abs(a)+abs(b)的位置 。

但是这个情况并不是通用的。(不然它为什么还要给你一个原地的方案,题目是不会给多余的条件的)

下面这种情况这样子是最优,但是题目不让连续走,于是我们就需要用到原地的方案。

 我们可以选择原地不动,那么如果a超出b的部分,我们必须选择原地不动,才能保证我们的路径最优。

 于是我们可以计算知道,我们可以先交替的走,然后再在那个位置往一个方向去走,往一个方向走的地方需要*2,较为长的位置是需要停一次,走一次,因此我们需要知道,题目所给的终点位置坐标,对于原点坐标来说,哪一个更长,长于1,因此我们可以推导出来:

(假设a长一些,b短一些)

最优=(a-b-1)*2+b*2+1

(a-b-1)*2代表已经走完了交替的路,直线的路,是需要俩次的。

b*2+1是指交替的路。

因此代码为:

#include<stdio.h>
#include<math.h>
int main()
{
	int sum=0;
	int ex,ey,t,i;
	scanf("%d",&t);
	for(i=0;i<t;i++)
	{
		scanf("%d%d",&ex,&ey);
		if(abs(abs(ex)-abs(ey))<2)
		{
			printf("%d\n",abs(ex)+abs(ey));
		}
		else 
		{
			if(abs(ex)>abs(ey))
			{
				sum=(abs(ex)-abs(ey)-1)*2+abs(ey)*2+1;
			}
			else 
			{
				sum=(abs(ey)-abs(ex)-1)*2+abs(ex)*2+1;
			}
			printf("%d\n",sum);
		}
	}
	return 0;
}

Problem - B - Codeforces

CF-B题

 1.这一题只是题目看起来有点唬人,主要算法我认为是贪心。

2.贪心的主要点在于,因为是一个递增序列,所以我们让当前需要新开一包的患者,等到 ta 的最长时刻,我们去开封一包,保证这包能够存活更久。

新开的这包最大时刻是 curmax 为: a[i]+w+d  如果往后的值  a[i]  都能小于curmax,就将剂量数减去1 ,满足上面的同时需要满足剂量还得使用。

在此过程计数即可。

 代码为:

#include<stdio.h>
#define N 200010
int a[N];
int main()
{
	int t,count,i,j,k,d,w,curmax,n;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d%d%d",&n,&k,&d,&w);
		//n是指患者数量,k是指一包的剂量数
		//d是指疫苗存活时间,w是指患者等待时间
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
		j=1;
		curmax=0;
		count=0;
		for(i=0;i<n;)
		{
			if(j==1)//开一包新的
			{
				count++;
				curmax=a[i]+w+d;
			}
			if(j<=k&&a[i]<=curmax)
			//试剂还有,并且在存活期内
			{
				j++;
				i++;
			}
			else 
			//该种情况是指试剂不够
			//和患者能等到的时间不在存活期内
			{
				j=1;
			}
		}
		printf("%d\n",count);
	}
}

简单搜索&&进阶搜索 - Virtual Judge (vjudge.net)

作业A题

1.这一题用的是BFS算法,特殊的点在于它是三维空间的。

2.我们了解S和E所出现的地方记录下标即可,然后去用队列去BFS它。需要注意的点是tail++语句的位置,不然会报错。

代码如下:

#include<stdio.h>
#define N 35
char arr[N][N][N];
int high,row,col;
struct node
{
	int h;
	int r;
	int c;
	int s;
}que[100000];
int head,tail;
int bfs()
{
	//左右,前后,上下
	int next[6][3]={{0,0,-1},{0,0,1},{0,-1,0},{0,1,0},{-1,0,0},{1,0,0}};
	int i,j,k,tx,ty,tk,book[N][N][N]={0};
	head=tail=0;
	struct node start,end;
	for(i=0;i<high;i++)//找起点和终点
	{
		for(j=0;j<row;j++)
		{
			for(k=0;k<col;k++)
			{
				if(arr[i][j][k]=='S')
				{
					start.h=i;
					start.r=j;
					start.c=k;
				}
				if(arr[i][j][k]=='E')
				{
					end.h=i;
					end.r=j;
					end.c=k;
				}
			}
		}
	}
	que[head]=start;
	book[start.h][start.r][start.c]=1;
	que[head].s=0;
	tail++;
	while(head<tail)
	{
		for(i=0;i<6;i++)
		{
			tx=que[head].h+next[i][0];
			ty=que[head].r+next[i][1];
			tk=que[head].c+next[i][2];

			if(tx<0||ty<0||tk<0||tx>=high||ty>=row||tk>=col) continue;
			
			if(arr[tx][ty][tk]=='#'||book[tx][ty][tk])
			{
				continue;
			}
			if(arr[tx][ty][tk]=='E')
			{
				return que[head].s+1;
			}
			if(arr[tx][ty][tk]=='.')
			{
			
				book[tx][ty][tk]=1;
				que[tail].h=tx;
				que[tail].r=ty;
				que[tail].c=tk;
				que[tail].s=que[head].s+1;
				tail++;
			}
		}
		head++;
	}
	return -1;
}
int main()
{
	int i,j,k,sum=0;//高,行,列
	scanf("%d%d%d\n",&high,&row,&col);
	while(high&&row&&col)
	{
		for(i=0;i<high;i++)//输入
		{
			for(j=0;j<row;j++)
			{
				scanf("%s",arr[i][j]);
			//	getchar();
			}
			getchar();
		}
		
		sum=bfs();
		if(sum>=0)	printf("Escaped in %d minute(s).\n",sum);
		else printf("Trapped!\n");
		scanf("%d%d%d\n",&high,&row,&col);		
	}
	return 0;
}

 简单搜索&&进阶搜索 - Virtual Judge (vjudge.net)

作业-C题

1.这一题是dfs算法,我们需要注意一点是,当我们完成搜索,可能另外一个搜索会停不下来,题目说了都在long long 范围之内,于是我们可以知道,long long大概是有19位数字,在搜索到第19位的时候是没必须要继续去搜索了。

2.因此需要判别一下,当到第19位便不再搜索。

代码如下:

#include<stdio.h>
unsigned long long min;
unsigned long long dfs(unsigned long long n,unsigned long long m,int step)
{
	if(m%n==0) 
	{
		min=m;
		return 0;
	}
	if(!min&&step<20) 
	{
		dfs(n,m*10,step+1);
		dfs(n,m*10+1,step+1);
	}
	return 0;
}
int main()
{
	unsigned long long m,n;
	scanf("%llu",&n);
	while(n)
	{
		min=0;
		dfs(n,1,1);
		printf("%llu\n",min);
		scanf("%llu",&n);
	}
}

简单搜索&&进阶搜索 - Virtual Judge (vjudge.net)

作业-D题

1.这一题纯暴力可以解决,但是需要在暴力上优化一下。

2.我们先记录初始俩个数组相连接起来的一个数组。

因为我们发现每一次改变数组时,其实就是下面这个样子,我们每次都按这个规律来,如果在过程中遇到了和题目所给的案列一样的就结束循坏去输出它,如果和我们保存的数组是一样的说明遇到循坏了,我们再怎么去找,也不会出现我们所想要的答案,所以结束循坏输出-1即可。

 代码如下:

#include<stdio.h>
#include<string.h>
int main()
{
	int t,i,j,k,nox;
	int len;
	char s1[110],s2[110],s3[220],s[220],temp[220];
	char lzy[220];
	scanf("%d",&t);
	for(i=1;i<=t;i++)
	{
		scanf("%d",&len);
		scanf("%s",s1);
		scanf("%s",s2);
		scanf("%s",s3);
		strcpy(temp,s1);
		strcat(temp,s2);
		for(k=0,j=0;k<len;k++)
		{
			s[j++]=s2[k];
			s[j++]=s1[k];
		}
		s[j]=0;
		for(nox=1;;nox++)
		{
			if(strcmp(s,s3)==0)
			{
				printf("%d %d\n",i,nox);
				break;
			}
			if(strcmp(temp,s)==0)
			{
				printf("%d %d\n",i,-1);
				break;
			}
			strcpy(lzy,s);
			for(j=0,k=0;j<len;j++)
			{
				s[k++]=lzy[j+len];
				s[k++]=lzy[j];
			}
			s[k]=0;
		}
	}
}

看《JAVA讲义》

主要学习了关于一些JAVA的知识。下面是一些我认为重要的一些知识。

类:是java语言中的最小程序单位,只有一个类能包含main函数,其实就是一个程序当中只能有一个主函数。

main函数格式通常是固定的。

public static void main(String[] args)

因为public所定义的类权限是最大的,static不依据对象来调用,需要直接通过类名来调用,直接使用主函数类名,void让主函数没有返回值,main函数的参数必须是字符串类型的,但是不一定取名为args,与c语言不一样的是,java主函数必须带参数,这个参数只是形式参数,用来获取命令行中用户输入进去的参数。

java源文件命名规则:

  1. 源文件后缀名必须是*.java
  2. 如果源文件没有public类,那么源文件名称可以随意取
  3. 如果有则必须和public名称一致。因此public类是只有一个的。

java严格区分大小写

java是面向对象语言,三大基本特征:封装、继承和多态。

在java语言当中除去8个基本类型外,其他的都是对象。对象具有状态,一个对象用数据值来描述他的状态。对象是java程序的核心,所以java里面的对象具有唯一性,每个对象都有一个标识来引用它,如果某个对象失去了标识,这个对象就会变成被回收。

具有相同或者相似性质的一组对象的抽象就是类。

java语言中使用class关键字来定义类,类主要有俩周结构关系。

  1. 一般->特殊关系:就是继承关系。
  2. 整体->部分关系:就是组合关系。

java语法标识符可以使用字符(中文字符或者日文字符)

java的所有关键字都是小写的,TRUE,FALSE,NULL不是java关键字

java默认数字为int型,如果你需要long,在数字后面加上大写或者小写的l,L。默认小数是double型,如果你想要浮点型,在后面加f,F即可。

java中二进制以0b或者0B开头,八进制以0开头,十六进制以0x或者0X开头。

java提供三个特殊的浮点数——正无穷大 (POSITIVE_INFINITY),负无穷大(NEGATIVE_INFINITY),和非数(NaN)。正无穷大是正数除以0,负无穷大是负数除以0,非数与任何值都不相同包括它自己。

java对于长的数字提供下划线写法,使数字分隔,但是不改变值,只是为了方便区分位数。

java中boolean类型只能用true和false来表示,不能使用0或者非0来表示,其他数据类型不能转换成布尔型。

java中+号可以作为字符串连接符号使用。

java会保证每个字符串常量只有一个。

求余运算符,不止用于整数,它的计算结构时第一个操作数除以第二个操作数,得到一个整除的结果后剩下的数字。所以求余运算符不可以求余0。

如果需要使用乘方、开方运算,需要借助java.lang.Math类的工具进去完成。具体就直接写Math.函数名()。c语言有的都有。

java有一个>>>符号,代表无符号右移运算符。

java 7支持switch语句中case 表达式是string和枚举。

java语言没有goto语句,但是它的break语句和continue语句十分灵活。单独写break语句是结束该循环,如果在break语句后跟一个标签,像这样:break:outer,中间写的是冒号,而后面的标识符可以自己定义,把标识符放在哪一层循坏外面就能结束哪一层循坏(如果在外循坏,可以结束外循坏的)。写法outer:(冒号),continue语句也是有一样的这个功能。

java语言定义数组:

type[] arrayname;

type arrayname[];

通常使用第一种。可以嵌套成二维数组。

数组是一种引用类型的变量,定义数组只是定义了一个引用变量,就是说指针。

数组初始化有俩种,静态初始化,和动态初始化

  1. 静态初始化:arrayname=new type[]{……},或者arrayname={……}。静态初始化通常指定类型
  2. 动态初始化:arrayname=new type[length],动态初始化能够指定长度。

java中所有数组都提供了length属性,可以直接访问到数组的长度。使用方法就是数组名称.length

java语言中有一个循坏叫foreach循坏,它会自动变量数组和集合的每个元素。

格式如下:

for(type variableName : array | collection)

{

       //variableName自动迭代访问每一个元素。

}

其中type是类型,variablename 是一个形参名称,斜率形参名字之后,可以在复合语句里面写这个形参名字,冒号后面需要是数组名称或者集合名称,花括号里面语句可以自己写,这个循坏的作用就是自动遍历元素。

java定义二维数组:type[][] arrname,也是可以使用静态初始化和动态初始化的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值