1.现有一个n*m的矩阵,矩阵中每个格子都有且只有一种颜色。矩阵中共有k种颜色,每个颜色通过特定数字C(i,j)表示。设初始位置位于(1,1),每次可以向右(x+1,y)者向下(x,y+1)移动一个单位。求从初始位置移动到(n,m)并且移动路径的中格子颜色均不相同的方案数。
输入描述:
1<= n,m <= 1e3
1 <= k<=14
1<=T<=4
1<= C(i,1) <= 1e8
输出描述:
第一行中表示输入数据组数接下来每组数据中:
第一行输入三个数字n,m,K
接下来n行,每行m个数字,代表每个网格的颜色数据保证颜色的种数一定等于k。
示例输入:
3
3 3 7
1 1 2
5 5 8
3 9 7
3 3 6
10 9 6
10 10 10
1 7 4
3 3 7
1 4 9
10 6 10
3 3 5
输出:
1
0
4
代码:(结束后写的,不知道能不能全AC,排除特殊情况,其他暴力递归)
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
public class Q2 {
public static int result = 0;
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int groupCount = scanner.nextInt();
for(int i=0;i<groupCount;i++){
int n = scanner.nextInt(); //矩阵行数
int m = scanner.nextInt(); //矩阵列数
int colorCount = scanner.nextInt();
int[][] colors = new int[n][m];
if(n+m-1>colorCount) {
System.out.println(0);
}else {
for(int h=0;h<m;h++){
for(int j=0;j<n;j++){
colors[h][j] = scanner.nextInt();
}
}
ArrayList<Integer> temp = new ArrayList<>();
temp.add(colors[0][0]);
train(temp,colors,0,0);
System.out.println(result);
result=0;
}
}
}
public static void train(ArrayList<Integer> trainColors,int[][] colors,int x,int y){
if(x==colors.length-1 && y==colors[0].length-1) result++;
if((x+1<=colors.length-1)&&(!trainColors.contains(colors[x+1][y]))){
trainColors.add(colors[x+1][y]);
train(trainColors,colors,x+1,y);
trainColors.remove(trainColors.size()-1);
}
if((y+1<=colors[0].length-1)&&(!trainColors.contains(colors[x][y+1]))){
trainColors.add(colors[x][y+1]);
train(trainColors,colors,x,y+1);
trainColors.remove(trainColors.size()-1);
}
}
}
2.有n个人排成一列,每个人身高不同,你知道第i个人前面有xi个人比他矮,求问如果按身高从矮到高排,每个人应该排在第几个位置。
输入:
4
0 1 1 0
输出:
2 4 3 1
思路:一个个插入排序,用题里的例子看,(0110分别对应着1234号人)即一开始1号排在第一队列为1(满足1号的条件),2号加入队列后队列变成12(满足2号的条件),3号加入队列后队列变成132(满足3号的条件),4号加入队列以后队列变成4132(满足4号的条件),所以说按照最后排好的顺序,应该输出2431(1234号分别在排好序的队伍中的顺序)
用arrayList
import java.util.*;
public class Q3 {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
String[] dataArr = scanner.nextLine().trim().split(" ");
int[] data = new int[dataArr.length];
for(int i=0;i<data.length;i++){
data[i] = Integer.parseInt(dataArr[i]);
}
List<Integer> result = new ArrayList<>();
for(int i=0;i<data.length;i++){
result.add(data[i],i+1);
}
HashMap<Integer,Integer> hashMap = new HashMap<>();
for(int i=0;i<result.size();i++)
hashMap.put(result.get(i),i+1);
for(int i=0;i<result.size();i++){
System.out.print(hashMap.get(i+1));
if(i!=result.size()) System.out.print(" ");
}
System.out.println("");
}
}
3.多多有一个X行Y列的棋盘,第i行第个格子的坐标记为(j),左上角的格子坐标为(1,1),右下角的格子坐标为(X.Y)。一个操作定义为(上,下,左,右)中的一种,可以将棋子移动到上下左右相邻的格子里,如果碰壁了就原地不动。多多有一个长度为N的操作序列,他希望将同样的操作序列应用于M个棋子上,求解每个棋子经过一系列操作后的最终坐标。
输入:
2(2组测试用例)
3 4 3 3(对应N M X Y N是操作序列长度、M是棋子数、X、Y是右下角的横纵坐标)
1 2 3(对应操作 1234分别对应上左下右)
1 1
1 3
2 2
3 1 (以上是四个棋子坐标)
0 1 1 1(操作序列长度为0代表不操作 所以这个用例少一行)
1 1
输出:
2 1
2 2
2 1
3 1
1 1
简化思路是把操作的序列分割成子序列来处理,同一段子序列里不能存在方向上的冲突,比如有向上的就不能出现向下的。建一个棋子类。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Q4 {
private static class Position{
private int x;
private int y;
private int maxX;
private int maxY;
Position(int x,int y,int maxX,int maxY){
this.x = x;
this.y = y;
this.maxX = maxX;
this.maxY = maxY;
}
public void move(int x,int y){
this.x = Math.max(Math.min(this.maxX,this.x+x),1);
this.y = Math.max(Math.min(this.maxY,this.y+y),1);
}
@Override
public String toString(){
return this.x +" "+this.y;
}
}
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int total = Integer.parseInt(scanner.nextLine());
for(int i=0;i<total;i++){
int[] data = parseInt(scanner.nextLine().split(" "));
String[] operates = null;
if(data[0]!=0){
operates = scanner.nextLine().split(" ");
}
ArrayList<Position> positions = new ArrayList<>();
for (int j=0;j<data[1];j++){
int[] xy = parseInt(scanner.nextLine().split(" "));
positions.add(new Position(xy[0],xy[1],data[2],data[3]));
}
if(data[0]==0){
for(int j=0;j<positions.size();j++){
System.out.println(positions.get(j).toString());
}
}else {
for(int j=0;j<positions.size();j++){
int x = 0;
int y = 0;
boolean onMove = true;
boolean leftMove = true;
for(int k=0;k<operates.length;k++){
switch (operates[k]){
case "1":
if(!onMove){
positions.get(j).move(x,y);
x = 0;
y = 0;
}
x--;
onMove = true;
break;
case "2":
if(!leftMove){
positions.get(j).move(x,y);
x = 0;
y = 0;
}
y--;
leftMove = true;
break;
case "3":
if(onMove){
positions.get(j).move(x,y);
x = 0;
y = 0;
}
x++;
onMove = false;
break;
case "4":
if(leftMove){
positions.get(j).move(x,y);
x = 0;
y = 0;
}
y++;
leftMove = false;
break;
}
}
positions.get(j).move(x,y);
System.out.println(positions.get(j).toString());
}
}
}
}
public static int[] parseInt(String[] strArr){
int[] result = new int[strArr.length];
for(int i=0;i<strArr.length;i++){
result[i] = Integer.parseInt(strArr[i]);
}
return result;
}
}
4.多多非常喜欢看书,所以多多买了很多书,并把这些书放在了个书架上,每个书架上放的书的数量分别为a1 a2.....an 多多将这些书架上的书按照顺序进行编号,第1个书架上的书编号为1到a1,第2个书架上的书编号为a1 +1 到a1+a2,依此类推。现在多多想找到m本书,编号分别为b1 b2...bm。求这m本书都在多少号书架上。
输入:
5(5个书架)
1 3 5 2 4(每个书架容量)
3(要找3本书)
4 2 7(这3本书的序号)
这题不用二分会超时
public class Main {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
int[] bookshelf = parseInt(scanner.nextLine().split(" "));
scanner.nextLine();
int[] data = parseInt(scanner.nextLine().split(" "));
for(int i=1;i<bookshelf.length;i++){
bookshelf[i] += bookshelf[i-1];
}
for(int book:data){
int index = Arrays.binarySearch(bookshelf,book);
if(index>=0){
index++;
}else {
index = -index;
}
System.out.println(index);
}
}
public static int[] parseInt(String[] strArr){
int[] result = new int[strArr.length];
for(int i=0;i<strArr.length;i++){
result[i] = Integer.parseInt(strArr[i]);
}
return result;
}
}