HNUCM-OJ算法练习14(JAVA)

问题 A: 统计字符串

题目描述

给定一个字符串str,返回str的统计字符串。例如“aaabbbbcccd”的统计字符串为“a_3_b_4_c_3_d_1”。

输入

输入一行字符串(1<=长度<=10^5)。

输出

输出一行字符串,代表统计字符串。

样例输入 Copy

offerofferzainaliiiiii
hhhaaa

样例输出 Copy

o_1_f_2_e_1_r_1_o_1_f_2_e_1_r_1_z_1_a_1_i_1_n_1_a_1_l_1_i_6
h_3_a_3

提示

时间复杂度O(n),空间复杂度O(n)。

import java.util.Scanner;
public class Main{
    public static void main (String[] args){
        Scanner cin=new Scanner(System.in);
        while(cin.hasNext()){
            String s=cin.nextLine();
        System.out.println(procrss(s));
        }
    }
 
    public static String procrss(String str){
      //为空的情况,直接return
        if(str.equals("")||str==null){
            return "";
        }
 
        StringBuffer  sbr = new StringBuffer();
        char c = str.charAt(0);
        int count =1;
        //循环做比较
        for(int i=1;i<str.length();i++){
            if(c==str.charAt(i)){
                count++;
            }
            else{
                sbr.append(c+"_"+count+"_");
                count = 1;
                c = str.charAt(i);
            }
        }
//最后一串的处理
      sbr.append(c+"_"+count);
        return sbr.toString();
    }
}

问题 B: 1的个数

题目描述

输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。

输入

输入一个整数(int类型)。

输出

这个数转换成2进制后,输出1的个数。

样例输入 Copy

5

样例输出 Copy

2

import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) {
 
        Scanner cin = new Scanner(System.in);
        while(cin.hasNext()){
      int n=cin.nextInt();
      System.out.println(Integer.bitCount(n));
        }
    }}
 

问题 C: 最小素数对

题目描述

任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对。

输入

输入一个偶数。

输出

输出两个素数。

样例输入 Copy

20

样例输出 Copy

7
13

import java.util.Scanner;
public class Main{
    //判断是否位素数
    public static boolean is_prime(int n) {
        for(int i=2;i<=Math.sqrt(n);i++) {
            if(n%i==0) {
                return false;
            }
        }
        return true;
    }
 
    public static void main (String[] args){
        Scanner cin=new Scanner(System.in);
        while(cin.hasNext()){
           int n=cin.nextInt();
           //二分
           int left=n/2-1;
           int right=n/2+1;
           while(!is_prime(left)||!is_prime(right)){
               left++;
               right--;
           }
           System.out.println(right);
            System.out.println(left);
        }
    }
 
 
 
 
}

问题 D: 自守数

题目描述

自守数是指一个数的平方的尾数等于该数自身的自然数。例如:25^2 = 625,76^2 = 5776,9376^2 = 87909376。请求出n以内的自守数的个数。

输入

int型整数。

输出

n以内自守数的数量。

样例输入 Copy

2000

样例输出 Copy

8

import java.util.Scanner;
public class Main{
   public static boolean trueorfalse(long x){
       long y=x*x;
        while(x>0&&y>0){
            if(x%10!=y%10)return false;
            x/=10;
            y/=10;
        }
        return true;
    }
 
    public static void main (String[] args){
        Scanner cin=new Scanner(System.in);
        int count=0;
        while(cin.hasNext()){
          long n=cin.nextInt();
          for(int i=0;i<=n;i++){
              if(trueorfalse(i)){
                  count++;
              }
          }
          System.out.println(count);
 
        }
    }
 
 
 
 
}

问题 E: 0-1背包问题(回溯法)

题目描述

有n个物品,第i个物品重量为wi,价值为vi,现有一背包容量为C,要求把物品装入背包得到最大价值,并且要求出这些选取的物品。 要求用回溯法求解。

输入

多组测试数据,请处理到文件尾,一个整数表示物品的数量n,后一行有n个整数,代表价值,再后一行有n个整数,代表重量,最后有一个整数C代表背包容量,1<=n<=15,1<=vi<=30,1<=wi<=30,1<=C<=80。

输出

背包的最大总价值和所选取的物品,如果选取的方案有多种,请输出字典序最小的那种方案,每组测试数据应输出一行,在这里字典序最小的意思是,我们假设存在两种不同方案S,T所能得到的总价值相同且是最大的,对于方案S种选取|S|种物品,方案T选取|T|种物品,对于i=1,2…j-1,我们有si = ti,但sj < tj,则方案的S的字典序比方案T的字典序要小。由于没有使用special judge,所以如果选取得方案是S,请按照从小到大的顺序输出方案S中的物品下标。

样例输入 Copy

5
6 3 6 5 4
2 2 4 6 5
8

样例输出 Copy

15 1 2 3

问题 F: 旅行售货员(TSP)

时间限制: 1 Sec 内存限制: 128 MB

提交: 138 解决: 60 201601090120

提交状态讨论版

题目描述

有若干个城市,任何两个城市之间的距离都是确定的,现要求一旅行商从某城市出发必须经过每一个城市且只在一个城市逗留一次,最后回到出发的城市,问如何事先确定一条最短的线路以保证路径最短?

输入

输入两个整数n,m分别代表城市数量,边数量,2<=n<=8,n-1<=m<=2*n
接下来m行每行输入有3个整数x,y,z代表x和y城市之间有一条长为z的路,保证输入的图是连通的,旅行商总是从1城市出发。

输出

要求求出最短的路径,和该路径的长度,如果不存在这样的路径你只需要输出-1。

样例输入 Copy

4 6
1 2 30
1 3 6
1 4 4
2 3 5
2 4 10
3 4 20

样例输出 Copy

1 3 2 4 1
25



import java.util.Scanner;

public class Main {
    static int n,m;//n城市数量,m边数量
    static int graph[][];
    static int curentlength,bestlength;//当前距离,最短距离
    static int curent[],best[];//当前路线,最好的路线
    static int MAX=Integer.MAX_VALUE;
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        while (cin.hasNext()) {
            n = cin.nextInt();
            m = cin.nextInt();
            graph = new int[n + 1][n + 1];
            curent = new int[n + 1];
            best = new int[n + 1];
            curentlength = 0;
            bestlength = -1;
            for (int i = 1; i <= n; i++) {
                curent[i] = i;
                for (int j = 1; j <= n; j++) {
                    graph[i][j] = MAX;//初始化地图
                }
            }
            for (int i = 1; i <= m; i++) {
                int S1 = cin.nextInt();
                int S2 = cin.nextInt();
                int length = cin.nextInt();

                graph[S1][S2] = length;
                graph[S2][S1] = length;//把所有的边存储起来

            }
            backtrace(2);
            if (bestlength != -1) {
                for (int i = 1; i <= n; i++) {
                    System.out.print(best[i] + " ");
                }
                System.out.println("1");

                System.out.println(bestlength);
            } else {
                System.out.println("-1");
            }

        }
    }

    private static void backtrace(int t) {
 

        if(t==n) {
            if(graph[curent[n-1]][curent[n]]!=MAX&&graph[curent[n]][1]!=MAX&&
                    (curentlength+graph[curent[n-1]][curent[n]]+graph[curent[n]][1]<bestlength||bestlength==-1)) {
   //1.当到准备去第n个城市的时候,首先要判断当前售货员与第n个点有没有路线,没有路线就剪掉
				//2.要判断第n个点与起点1有没有路线,没有也要剪掉
				//3.判断走完这条路线,回到原点的总距离是不是小于已经知道的最短距离,如果大于也剪掉
				//如果都符合,就要做更新操作
                for(int i=1;i<=n;i++) {
                    best[i]=curent[i];
                }
                bestlength=curentlength+graph[curent[n-1]][curent[n]]+graph[curent[n]][1];
            }
        }else {
            for(int i=t;i<=n;i++) {
                if(graph[curent[t-1]][curent[i]]<MAX&&(curentlength+graph[curent[t-1]][curent[i]]<bestlength||bestlength==-1)) {
//上面的剪枝条件是,t-1表示现在售货员所在的城市,i表示他现在要准备去的城市,两者之间必须要有边
					//bestlength=-1表示第一次走
					//符合条件我们就需要交换
                    swap(t,i);
                    curentlength=curentlength+graph[curent[t-1]][curent[t]];
                    backtrace(t+1);
                    curentlength=curentlength-graph[curent[t-1]][curent[t]];
                    swap(t,i);

                }
            }
        }

    }
    //交换函数
    private static void swap(int t, int i) {
        int temp=0;
        temp=curent[t];
        curent[t]=curent[i];
        curent[i]=temp;
    }

}







猜你喜欢

转载自blog.csdn.net/qq_45353823/article/details/106242718