题目A
数字计数
给出n个数字,请你求出在给出的这n个数字当中,最大的数字与次大的数字之差,最大的数字与次小的数字之差,次大的数字与次小的数字之差,次大的数字与最小的数字之差.
对于%30%的数据,保证n \leq 8n≤8
对于%60%的数据,保证n\leq 16n≤16
对于%100%的数据,保证n\leq100n≤100
对于所有数据,保证每个数字小于等于100且不同数字的个数大于4
思路
签到题,注意去重就好了。
代码
import java.util.*;
public class Main{
public static void main(String args[])
{
Scanner reader=new Scanner(System.in);
int n=reader.nextInt();
int array[]=new int[n];
for(int i=0;i<n;++i)
array[i]=reader.nextInt();
Arrays.sort(array);
int max=array[n-1];
int min=array[0];
int second_min=0;
int second_max=0;
for(int i=1;i<n;++i)
{
if(array[i]!=min)
{
second_min=array[i];
break;
}
}
for(int i=n-2;i>=0;--i)
{
if(array[i]!=max)
{
second_max=array[i];
break;
}
}
System.out.println((max-second_max)+" "+(max-second_min)+" "+(second_max-second_min)+" "+(second_max-min));
}
}
结果
A了,简单题,没什么好总结的
题目B
MoveToEx找到了很多不同颜色的珠子,他把这些珠子排成了一列,每个珠子的颜色用1,2…表示.定义一个区间的美观度为区间中不同颜色的珠子个数现在MoveToEx想知道,在所有n * (n+1)/2个区间中,所有区间的美观度之和是多少.
思路
我们可以知道,假设下标从1开始,那么从1到3的不同颜色珠子的个数是以从1到2的不同颜色珠子的个数为基础的。我们可以利用一个标记数组,来找出一行的不同珠子的情况,并存放在dp数组中,dp数组的含义就是当前的位置i截取到位置j的长度的不同珠子的个数。
代码
import java.util.Scanner;
public class Main{
public static void main(String args[]){
Scanner reader=new Scanner(System.in);
int n=reader.nextInt();
//存放各个数字
int nums[]=new int[1200];
for (int i=1;i<=n;++i)
nums[i]=reader.nextInt();
//动态数组
int dp[][]=new int[1200][1200];
//对角线上的数值都是1
for (int i=1;i<=n;++i)
dp[i][i]=1;
int visited[]=new int[1200];
for (int i=1;i<=n;++i)
{
visited[nums[i]]=1;//在当前这个以位置i起始的地方,所有出现过得数字,就标记为1
for (int j=i+1;j<=n;++j)
{
if (visited[nums[j]]==0)
{
dp[i][j]=dp[i][j-1]+1;
visited[nums[j]]=1;
}
else
{
dp[i][j]=dp[i][j-1];
}
}
for (int g=0;g<1200;++g)//初始化标记
visited[g]=0;
}
int count=0;//计算总数
for(int i=1;i<=n;++i)
{
for (int j=i;j<=n;++j)
count+=dp[i][j];
}
System.out.println(count);
}
}
总结
也是简单题,就是把当前位置为起始的看做是一个,然后,拓展为二维数组那样来计算。最后,只需要计算一个上三角形即可。也不算难题。
题目C
智斗恶龙
链接:https://ac.nowcoder.com/acm/contest/7226/C
来源:牛客网
MoveToEx来到了一个异次元世界,在这个世界中存在着恶龙.作为拯救世界的勇士,MoveToEx要打倒恶龙.
为了寻找能打倒恶龙的能力,MoveToEx来到了一个地宫中.MoveToEx在刚到达地宫时,他因为传送魔法的原因,被传送到了(sx,sy)的位置,而由于这个地宫中特有的封印值d,MoveToEx只能到达那些他需要走小于等于d步就能到达的格子.在这个地宫中的某些格子中存在着一些宝藏,当MoveToEx来到这些存在宝藏的格子上时,他可以获得这些格子上的宝藏,当然他也可以选择不获取这些格子上的宝藏.每个宝藏有其特殊的能力值.为了打败恶龙,MoveToEx至少需要x种不同能力的宝藏,但是由于MoveToEx的身体无法承受太强烈的能量差距,所以他希望他所使用的宝藏的最大与最小的能力值之差最小.
当然,地宫中有一些陷阱,MoveToEx在地宫中时不能经过这些陷阱.
所以请你帮助MoveToEx计算一下,MoveToEx所使用宝藏的最大与最小的能力值之差.
思路
先进行广搜,搜到所有已当前位置可以拓展到的点,把他们的能量都加入到集合中【因为打败恶龙要使用不同的能力值,所以要进行去重】,再把数据从集合【自动去重】的数据存放到数组中,进行排序,并且每次取出相应的个数的首尾两个数值进行相减,枚举一遍,得到最小值即可。
代码
import java.util.*;
class Point{
int x; //横坐标
int y; //纵坐标
int step;//到达该店所需要的步数
}
public class Main{
static int n;
static int m;
static int sx;
static int sy;
static int d;
static int x;
static long map[][]=new long[1005][1005];//地图
static int visited[][]=new int[1005][1005];//标记数组
static Queue<Point> queue=new LinkedList();
static HashSet<Long> set=new HashSet();
//右下左上
static int d_x[]={0,1,0,-1};
static int d_y[]={1,0,-1,0};
public static void main(String[] args) {
Scanner reader=new Scanner(System.in);
int T=reader.nextInt();//T组测试数据
for (int g=0;g<T;++g)
{
n=reader.nextInt();//行数
m=reader.nextInt();//列数
sx=reader.nextInt();//出发初始横坐标
sy=reader.nextInt();//出发初始列坐标
d=reader.nextInt();//限制走的步数
x=reader.nextInt();//打败恶龙所需要的宝藏数目
for (int i=1;i<=n;++i)
{
for (int j=1;j<=m;++j)
{
map[i][j]=reader.nextLong();//接受地图
visited[i][j]=0;//初始化标记数组
}
}
queue.clear();//初始化队列
set.clear();//清空集合
if (map[sx][sy]==-1)
{
System.out.println("no");
continue;
}
Point temp=new Point();
temp.x=sx;
temp.y=sy;
temp.step=0;
visited[sx][sy]=1;//已经访问
queue.offer(temp);
while (!queue.isEmpty())
{
int a_x=queue.peek().x;
int a_y=queue.peek().y;
int step=queue.peek().step;
//大于0才加入
if (map[a_x][a_y]>0)
set.add(map[a_x][a_y]);
for (int i=0;i<=3;++i)
{
int temp_x=a_x+d_x[i];
int temp_y=a_y+d_y[i];
int temp_steps=step+1;
if (check(temp_x,temp_y,temp_steps))
{
Point temporary=new Point();
temporary.x=temp_x;
temporary.y=temp_y;
temporary.step=temp_steps;
visited[temp_x][temp_y]=1;
queue.offer(temporary);
}
}
queue.poll();
}
int length=set.size();
long result[]=new long[length];
Iterator it=set.iterator();
int index=0;
while (it.hasNext())
{
result[index++]=(long)it.next();
}
Arrays.sort(result);
long min=Long.MAX_VALUE;
if (length<x)
System.out.println("no");
else
{
for (int i=0;i+x-1<length;++i)
{
long k= result[i+x-1]-result[i];
if (k<min)
min=k;
}
System.out.println(min);
}
}
}
public static boolean check(int a,int b,int steps)
{
return a>0 && a<=n && b>0 && b<=m && visited[a][b]==0 && map[a][b]>=0 && steps<=d;
}
}
结果
ac了,有两个坑点,
一个是,如果起始位置是一个陷阱,那么就没有搜索的必要的,直接输出no即可;
另外一个坑点是,数据是比int类型大的,要使用long类型才不会溢出。
以后,尽量都使用long,避免因为这个而导致wa。
第四道题,没做出来。