目录
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;
}
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源文件命名规则:
- 源文件后缀名必须是*.java
- 如果源文件没有public类,那么源文件名称可以随意取
- 如果有则必须和public名称一致。因此public类是只有一个的。
java严格区分大小写
java是面向对象语言,三大基本特征:封装、继承和多态。
在java语言当中除去8个基本类型外,其他的都是对象。对象具有状态,一个对象用数据值来描述他的状态。对象是java程序的核心,所以java里面的对象具有唯一性,每个对象都有一个标识来引用它,如果某个对象失去了标识,这个对象就会变成被回收。
具有相同或者相似性质的一组对象的抽象就是类。
java语言中使用class关键字来定义类,类主要有俩周结构关系。
- 一般->特殊关系:就是继承关系。
- 整体->部分关系:就是组合关系。
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[];
通常使用第一种。可以嵌套成二维数组。
数组是一种引用类型的变量,定义数组只是定义了一个引用变量,就是说指针。
数组初始化有俩种,静态初始化,和动态初始化
- 静态初始化:arrayname=new type[]{……},或者arrayname={……}。静态初始化通常指定类型
- 动态初始化:arrayname=new type[length],动态初始化能够指定长度。
java中所有数组都提供了length属性,可以直接访问到数组的长度。使用方法就是数组名称.length
java语言中有一个循坏叫foreach循坏,它会自动变量数组和集合的每个元素。
格式如下:
for(type variableName : array | collection)
{
//variableName自动迭代访问每一个元素。
}
其中type是类型,variablename 是一个形参名称,斜率形参名字之后,可以在复合语句里面写这个形参名字,冒号后面需要是数组名称或者集合名称,花括号里面语句可以自己写,这个循坏的作用就是自动遍历元素。
java定义二维数组:type[][] arrname,也是可以使用静态初始化和动态初始化的。