目录
包装类
单例设计模式
类的成员——初始化块
final关键字
抽象类
模块设计模式
接口
类的成员——内部类
集合
HashSet集合
TreeSet集合
List集合
map集合
工具类conllections
泛型
泛型类
泛型接口
报错的情况
泛型方法
泛型通配符
有限制的通配符
cf
Java有一个非常明显的特点,它有很多类,类中有方法,用户可以通过调用类,来解决问题,与其自己再创造类,学会调用已知的类,效果可能会更好。
一般new对象太费力,或者需要频繁地new新的但没有必要的对象,就使用单例设计模式。
对变量起限制作用
final修饰的方法不能被子类重写。
abstract关键字
只要类中有一个抽象方法,类就必须是抽象类、
抽象类体现的就是一种模块模式的设计,它作为多个子类的通用模板。
父类一般不要去改,因为一旦改了父类,它下面的子类就会受影响,但是有时候又确实需要对父类扩展方法,一般这种时候就新建接口,然后再在接口上新建方法,其它的子类有类似需求的,也可以新建接口。
通俗点讲就是,父类已经满足不了子类的需求了,那我就要自食其力去创建这个东西,自食其力创建的就是接口。
让集合添加我指定的类型,从而限制类型,更安全。
简单搜索&&进阶搜索 - Virtual Judge
分析:
这个题目究其本质就是一个全排列,但是要记得回溯。
具体实现就是创建一个二维数组,对可以连接i的每个元素的值都赋1,然后这其实就已经实现了字典序的排列,然后从起点开始找,回到起点就结束,然后输出。
#include
#include
#include
int m;
int a[21][21],aa[25];
int b[25];
int k=1;
void dfs(int c,int d)
{
if(d==20&&!a[c][m])
return;
if(d==20&&a[c][m])
{
printf("%d: ",k);
k++;
for(int i=0;i<20;i++)
printf("%d ",aa[i]);
printf("%d",m);
printf("\n");
return;
}
for(int i=1;i<=20;i++)
{
if(a[i][c]&&!b[i])
{
b[i]=1;
aa[d]=i;
dfs(i,d+1);
b[i]=0;
}
}
}
int main()
{
for(int i=1;i<=20;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
a[i][x]=1;
a[i][y]=1;
a[i][z]=1;
}
scanf("%d",&m);
while(m)
{
k=1;
aa[0]=m;
for(int i=0;i<21;i++)
b[i]=0;
b[m]=1;
dfs(m,1);
scanf("%d",&m);
}
}
https://vjudge.net/contest/547627#problem/G
分析:
这个题可以用双向广搜,但是我是用了两次广搜,然后加起来比较找最小。
这里有一个小坑点就是,判断哪个kfc的距离最短的时候,还要判断这两个人是否都能到这个kfc,但凡有一个人没有到,这个kfc都不能作为两个人会面的场所。
还有就是她们两个走过的地方都必须标记并且记录以便于判断。
#include
#include
#include
int m,n;
int a[2][201][201],xx,yy,k;
char c[201][201],cc;
int b[201][201];
int d[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
struct fff
{
int x;
int y;
int s;
}map[201*201];
void cz(char ccc)
{
for(int i=0;i=n||ny<0||ny>=m||b[nx][ny]||c[nx][ny]=='#')
continue;
b[nx][ny]=1;
map[tail].x=nx;
map[tail].y=ny;
map[tail].s=map[head].s+1;
a[k][nx][ny]=map[tail].s;
tail++;
}
head++;
}
}
void minn()
{
int min=400000;
for(int i=0;i
简单搜索&&进阶搜索 - Virtual Judge
分析:
这个题主打的就是一个记录,记录路径,记录次数。(副主打判断)
我写得有点臃肿,但思路没什么大问题,它还是一个广搜,但是它的结构要多的就是它的记录它之前做的动作,进入循环先判断,是不是达到了要求的水量,达到就输出,根据记录的路径选择性的输出,在搜索时它一共有6个状态,所以对于每一个“head”都要判断六次。
它每一次倒水都要进行记录,记住是每一次,记住这个路径,之后直接输出就行。
这个题没有坑点,但是脑袋一定要清楚,我下面该判断什么,该怎么判断,判断成功怎么赋值,怎么给路径。
#include
#include
#include
int a,b,c;
int book[1005][1005];
struct fff
{
int aa;
int bb;
int bs;
int k;
char jl[1005];
}arr[1005*1005];
void bfs()
{
int tail,head;
head=tail=0;
arr[tail].aa=0;
arr[tail].bb=0;
arr[tail].bs=0;
book[0][0]=1;
arr[tail].k=0;
arr[tail].jl[0]=0;
tail++;
while(head=b&&!book[q.bb-b][b])
{
book[q.bb-b][b]=1;
arr[tail].aa=q.bb-b;
arr[tail].bb=b;
arr[tail].bs=p.bs+1;
strcpy(arr[tail].jl,p.jl);
arr[tail].jl[p.k]=i+'0';
arr[tail].k=p.k+1;
arr[tail].jl[arr[tail].k]=0;
tail++;
}
}
if(i==5)//把b倒给a
{
struct fff q;
q.aa=p.aa+p.bb;
if(q.aa=a&&!book[a][q.aa-a])
{
book[a][q.aa-a]=1;
arr[tail].aa=a;
arr[tail].bb=q.aa-a;
arr[tail].bs=p.bs+1;
strcpy(arr[tail].jl,p.jl);
arr[tail].jl[p.k]=i+'0';
arr[tail].k=p.k+1;
arr[tail].jl[arr[tail].k]=0;
tail++;
}
}
}
}
printf("impossible\n");
}
int main()
{
scanf("%d%d%d",&a,&b,&c);
bfs();
}
这场cf的第一题没什么难度,其实第二题也没什么难度,但是自己想岔了一个点,就一直出不来。
Problem - B - Codeforces
分析:
首先要明白它这个数组里面的数是可以随意变换位置的,也就是说你想让它放在哪里就放在哪里,所以我最开始的想法的就是以0的个数为界限,分为三大块。第一大块,全是0的情况,那结果就是1;第二大块,0比非0数的个数少的情况,那么那些非零数是可以插空的,所以结果为0;第三大块,也就是我昨天出问题的地方,我多想了一个3,我当时想着如果0比非零数的个数多,我就把所有的非零数往后堆,那就会出现“00000111”的情况,我觉得就是3,但是其实不是,如果把它插空“01010100”,那么它的结果应该是2,所以最后一大块的判断分两部分,第一部分,如果它的最大值就是1,那么结果是2;如果最大值比1大,那结果就是1,就像“00000311”,这里的原理就是只要我的最大比1大,那我就把这个最大值放在一堆数的最前面,后面的数两两相加,一定都会大于或等于2.
代码如下:
#include
#include
#include
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int l1=0;//0的数量
int max=-1;
for(int i=0;i