2018級《算法分析與設計》練習6

問題 C: 與7相關的數

題目描述

一個正整數,如果它能被7整除,或者它的十進制表示法中某個位數上的數字爲7, 則稱其爲與7相關的數。
現求所有小於等於n(n<100)的與7無關的正整數的平方和。

輸入

案例可能有多組。對於每個測試案例輸入爲一行,正整數n,(n<100)。

輸出

對於每個測試案例輸出一行,輸出小於等於n的與7無關的正整數的平方和。

樣例輸入 Copy

21

樣例輸出 Copy

2336

import java.util.Scanner;
 
public class Main {
     public static boolean isIn7(int a) {
         if(a%7==0) {return true;}
           int temp=a;
            while(temp>0){
                if(temp%10==7){
                    return true;
                }
                temp /=10;
            }
            return false;
      
       }//判斷是否包含7
    public static void main(String[] args) {
        //一個正整數,如果它能被7整除,或者它的十進制表示法中某個位數上的數字爲7, 則稱其爲與7相關的數。
        // 現求所有小於等於n(n<100)的與7無關的正整數的平方和。
        Scanner cin=new Scanner(System.in);
        while(cin.hasNext()) {
            int n=cin.nextInt();
            int sum=0;
            for(int i=1;i<=n;i++) {
                if(!isIn7(i)) {
                sum+=i*i;
                }
            }
            System.out.println(sum);
             
             
        }
         
        }
}

問題 B: 雞兔共籠

題目描述

一個籠子裏面關了雞和兔子(雞有2只腳,兔子有4只腳,沒有例外)。
已經知道了籠子裏面腳的總數a,問籠子裏面至少有多少隻動物,至多有多少隻動物。

輸入

每組測試數據佔1行,每行一個正整數a (a < 32768)。

輸出

輸出包含n行,每行對應一個輸入,包含兩個正整數,第一個是最少的動物數,第二個是最多的動物數,兩個正整數用一個空格分開。
如果沒有滿足要求的答案,則輸出兩個0。

樣例輸入 Copy

2
3
20

樣例輸出 Copy

0 0
5 10

import java.util.Scanner;
 
public class Main {
   
    public static void main(String[] args) {
         
        Scanner cin=new Scanner(System.in);
        int n=cin.nextInt();
        while(n>0) {
            int m=cin.nextInt();
            if(m%2!=0) {
                System.out.print(0);
                System.out.print(" ");
                System.out.println(0);
            }else {
                int min,max;
                int q,r,e;
                int canyu,canyu2;
                q=m/2;
                canyu=m%2/4;
                max=q+canyu;
                e=m/4;
                canyu2=m%4/2;
                min=canyu2+e;
                System.out.print(min);
                System.out.print(" ");
                System.out.println(max);
                 
            }
            n--;
        }
        }
}

問題 C: 買房

題目描述

某程序員開始工作,年薪N萬,他希望在中關村公館買一套60平米的房子,現在價格是200萬。
假設房子價格以每年百分之K增長,並且該程序員未來年薪不變,且不吃不喝,不用交稅。
每年所得N萬全都積攢起來,問第幾年能夠買下這套房子(第一年房價200萬,收入N萬)。

輸入

有多行,每行兩個整數N(10<=N<=50), K(1<=K<=20)。

輸出

針對每組數據,如果在第21年或者之前就能買下這套房子,則輸出一個整數M,表示最早需要在第M年能買下,否則輸出Impossible,輸出需要換行。

樣例輸入 Copy

50 10
40 10
40 8

樣例輸出 Copy

8
Impossible
10

#include<iostream>
using namespace std;
int main()
{
    double n;
    double k;
    while(cin>>n>>k)
    {
            double y=1;
      
    double M=200;
        double All=n;
    while(true)
    {
        All+=n;
        M*=(1+k/100);
        if(All>M)
        {
            cout<<y+1<<endl;
            break; 
        }
        if(y>20)
        {
        cout<<"Impossible"<<endl;
        break;
        }
        y++;
    }
}
    return 0;
 }
  
 

問題 D: 棋盤覆蓋問題

題目描述

在一個n×n (n = 2k)個方格組成的棋盤中,恰有一個方格與其他方格不同,稱該方格爲一特殊方格,且稱該棋盤爲一特殊棋盤。
在棋盤覆蓋問題中,要用圖示的4種不同形態的L型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個L型骨牌不得重疊覆蓋。

輸入

多組測試用例,每組測試用例包括兩部分,
第一部分爲方格的寬度n,
第二部分則爲方格,特殊方格爲-1,其他方格爲0。

輸出

輸出覆蓋後的方案

樣例輸入 Copy

4
-1 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

樣例輸出 Copy

-1 2 4 4
2 2 1 4
3 1 1 5
3 3 5 5

#include <iostream>
#include <cstring>
#include <cstdio>
  
using namespace std;
//tr表示棋盤左上角行號
//tc表示棋盤左上角列號
//dr表示特殊棋盤的行號
//dc表示特殊棋盤的列號
//size = 2^k
//棋盤的規格爲2^k * 2^k
 
 
int tile=1;
static int board[8][8];
void chessBoard(int tr, int tc, int dr, int dc, int size) {
      if (size == 1) return;
      int t = tile++,  // L型骨牌號
      s = size/2;  // 分割棋盤
                                                         // 覆蓋左上角小棋盤
      if (dr < tr + s && dc < tc + s)
         // 特殊方格在此棋盤中
         chessBoard(tr, tc, dr, dc, s);
      else {// 此棋盤中無特殊方格
         // 用 t 號L型骨牌覆蓋右下角
         board[tr + s - 1][tc + s - 1] = t;
         // 覆蓋其餘方格
         chessBoard(tr, tc, tr+s-1, tc+s-1, s);}
                                                                     // 覆蓋左下角小棋盤
      if (dr >= tr + s && dc < tc + s)
         // 特殊方格在此棋盤中
         chessBoard(tr+s, tc, dr, dc, s);
      else {// 用 t 號L型骨牌覆蓋右上角
         board[tr + s][tc + s - 1] = t;
         // 覆蓋其餘方格
         chessBoard(tr+s, tc, tr+s, tc+s-1, s);}
            
   
                                                         // 覆蓋右上角小棋盤
      if (dr < tr + s && dc >= tc + s)
         // 特殊方格在此棋盤中
         chessBoard(tr, tc+s, dr, dc, s);
      else {// 此棋盤中無特殊方格
         // 用 t 號L型骨牌覆蓋左下角
 board[tr + s - 1][tc + s] = t;
         // 覆蓋其餘方格
         chessBoard(tr, tc+s, tr+s-1, tc+s, s);}
                                                            // 覆蓋右下角小棋盤
      if (dr >= tr + s && dc >= tc + s)
         // 特殊方格在此棋盤中
         chessBoard(tr+s, tc+s, dr, dc, s);
      else {// 用 t 號L型骨牌覆蓋左上角
         board[tr + s][tc + s] = t;
         // 覆蓋其餘方格
         chessBoard(tr+s, tc+s, tr+s, tc+s, s);}
         
    
   }
 
 
 
int main()
{   int i,j;
int x,y;
int n;
    while(scanf("%d",&n)!=EOF){
    for(i=0;i<n;i++){
        for(j=0;j<n;j++){
            scanf("%d",&board[i][j]);
        }
    }
    //尋找特殊點座標 
        for(i=0;i<n;i++){
        for(j=0;j<n;j++){
            if(board[i][j]==-1){
                x=i;
                y=j;
            }
        }
    }
 
    chessBoard(0,0,x,y,n);
     for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
             
            cout<<board[i][j]<<" ";
        }
       cout<<endl;
    }
    //初始化 
    tile=1;
     for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            board[i][j]=0;
        }
}
  }
    return 0;
}
 

問題 E: 大整數乘法

題目描述

使用分治算法實現兩個大整數相乘。

輸入

兩個十進制大整數,滿足每一個整數長度爲2^n且兩個大整數的長度相等。(多組數據)

輸出

兩個大整數的乘積。

樣例輸入 Copy

1234 5678

樣例輸出 Copy

7006652

#include<stdio.h>
#include<stdbool.h> 
#include<math.h>
 int sign(long value){
    return value>0?1:-1;
 }          
 long solve(long x,long y,int n){
    int s=sign(x)*sign(y);//判斷符號
    x=abs(x);
    y=abs(y);
    if(x==0||y==0){
        return 0;
    } 
    else if(n==1){
            return s*x*y;}
    else{
        long A=(long)(x/pow(10,n/2));
        long B=(x%(long)pow(10,n/2));
        long C=(long)(y/pow(10,n/2));
        long D=(y%(long)pow(10,n/2));
        long AC=solve(A,C,n/2);
        long BD=solve(B,D,n/2);
        long ABCD=solve((A-B),(D-C),n/2)+AC+BD;
        return (long)(s*(AC*pow(10,n)+ABCD*pow(10,n/2)+BD));
    }
 }
 int len(int n){
    int count=0;
  while(n != 0)
    {
         
        // n = n/10
        n /= 10;
        ++count;
    }
    return count;
 }//計算位數 
int main(){
    long n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
 
    int leng=len(n);
    printf("%d\n",solve(n,m,leng)); }
     
     
    
 
     
}

問題 F: 第k小元素問題

題目描述

輸入一個整數數組,請求出該數組的第k小元素。要求時間複雜度爲O(n)。

輸入

每組輸入包括兩行,第一行爲一個整數數組,兩個數字之間用空格隔開;第二行爲k值。數組中元素個數小於10^9。

輸出

輸出第k小元素的值。

樣例輸入 Copy

2 5 6 1 8 7 9
2

樣例輸出 Copy

2

#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
vector<int>v;
int i,j;
 
int main(){
    int y;
    int lenght;
    while(~scanf("%d",&y)){
        v.push_back(y);
        int x;
        while(scanf("%d",&x)){
            v.push_back(x);
            if(getchar()=='\n')
            break;
        }
        sort(v.begin(),v.end());
        int k;
        scanf("%d",&k);
        printf("%d\n",v[k-1]);
        v.clear();//清空vector 
     
}
} 

問題 G: 找中位數

題目描述

請設計一個算法,不排序,快速計算出一個無序數列的中位數。 時間複雜度要求爲O(n)。
如果有奇數個元素,中位數則是數組排序後最中間的那個數字。
如果是偶數個元素,中位數則是數組排序後最中間兩個元素的平均值。

輸入

有多組輸入,每組輸入的第一行爲n(1<=n<=1e5),表示該數列的元素個數。
第二行爲n個整數組成的無序數列

輸出

每組樣例輸出一行,表示該無序數列的中位數。
若爲偶數,請保留三位小數
若爲奇數,直接輸出

樣例輸入 Copy

5
5 3 2 1 4

樣例輸出 Copy

3

import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
    public static void swap(int a[],int p,int q) {
        int t;
        t=a[p];
        a[p]=a[q];
        a[q]=t;
    }
 
    public static int partition(int a[],int p,int q) {
        int x=a[p];
        int i=p,j;
        for(j=p+1;j<=q;j++) {
            if(a[j]<x) {
                i++;
                swap(a,i,j);
            }
        }
        swap(a,p,i);
        return i;
    }
 
   public static void getMid(int a[],int p,int q) {
       int mid=(p+q)/2;
       while(true) {
           int pos=partition(a,p,q);
           if(pos==mid)break;
           else if(pos>mid) {q=pos-1;}
           else {p=pos+1;}
       }
      if(a.length%2!=0) {
       System.out.println(a[mid]);}
      else {
          
          double MID=1.0*(a[mid]+a[mid+1])/2;
          System.out.println(String.format("%.3f", MID));
      }
   }
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        while(cin.hasNext()) {
       int n=cin.nextInt();
       int a[]=new int[n];
       for(int i=0;i<a.length;i++) {
           a[i]=cin.nextInt();
       }
       getMid(a,0,a.length-1);
         
        }
         
    }
}

問題 H: 矩陣乘法

題目描述

設M1和M2是兩個n×n的矩陣,使用分治法計算M1×M2 的乘積。n爲2^k,且k<=10。

輸入

一個整數n表示矩陣的維數,接下來n行爲第一個矩陣,再下面n行爲第二個矩陣。

輸出

矩陣的乘積(兩個數字之間空一格,數字右對齊)。

樣例輸入 Copy

2
1 1
2 2
3 3
4 4

樣例輸出 Copy

7 7
14 14

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Scanner;
 
 
public class Main {
   
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n=cin.nextInt();
        int[][] Matrix1=new int[n+1][n+1] ;
        int[][] Matrix2=new int[n+1][n+1];
        int [][] ans=new int[n+1][n+1];
        DecimalFormat df=new DecimalFormat("-");
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) {
                Matrix1[i][j]=cin.nextInt();
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) {
                Matrix2[i][j]=cin.nextInt();
            }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=n;j++) {
            for(int k=1;k<=n;k++) {
                ans[i][j]+=Matrix1[i][k]*Matrix2[k][j];
            }
            }
            }
        for(int i=1;i<=n;i++){  
            for(int j=1;j<=n;j++) {
                System.out.printf("%2d",ans[i][j]);   
                System.out.print(" ");
                }
            System.out.println();
            }
         
          
        }
}

問題 I: Matrix multiplication

題目描述

Given two matrices A and B of size n×n, find the product of them.

bobo hates big integers. So you are only asked to find the result modulo 3.

輸入

The input consists of several tests. For each tests:

The first line contains n (1≤n≤800). Each of the following n lines contain n integers – the description of the matrix A. The j-th integer in the i-th line equals Aij. The next n lines describe the matrix B in similar format (0≤Aij,Bij≤109).

輸出

For each tests:

Print n lines. Each of them contain n integers – the matrix A×B in similar format.

樣例輸入 Copy

1
0
1
2
0 1
2 3
4 5
6 7

樣例輸出 Copy

0
0 1
2 1

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Scanner;
 
 
public class Main {
   
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n=cin.nextInt();
        int[][] Matrix1=new int[n+1][n+1] ;
        int[][] Matrix2=new int[n+1][n+1];
        int [][] ans=new int[n+1][n+1];
        DecimalFormat df=new DecimalFormat("-");
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) {
                Matrix1[i][j]=cin.nextInt();
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) {
                Matrix2[i][j]=cin.nextInt();
            }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=n;j++) {
            for(int k=1;k<=n;k++) {
                ans[i][j]+=Matrix1[i][k]*Matrix2[k][j];
            }
            }
            }
        for(int i=1;i<=n;i++){  
            for(int j=1;j<=n;j++) {
                System.out.printf("%2d",ans[i][j]);   
                System.out.print(" ");
                }
            System.out.println();
            }
         
          
        }
}
          

問題 J: 機器人的指令

題目描述

數軸原點有一個機器人。該機器人將執行一系列指令,你的任務是預測所有指令執行完畢之後它的位置。

LEFT:往左移動一個單位

RIGHT: 往右移動一個單位

SAME AS i: 和第i條執行相同的動作。輸入保證i是一個正整數,且不超過之前執行指令數

輸入

輸入第一行爲數據組數T (T<=100)。每組數據第一行爲整數n (1<=n<=100),即指令條數。以下每行一條指令。指令按照輸入順序編號爲1~n。

輸出

對於每組數據,輸出機器人的最終位置。每處理完一組數據,機器人應復位到數軸原點。

樣例輸入 Copy

2
3
LEFT
RIGHT
SAME AS 2
5
LEFT
SAME AS 1
SAME AS 2
SAME AS 1
SAME AS 4

樣例輸出 Copy

1
-5

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char s[10],c[10];
int a[100];
int main()
{
  int T,n,m;
  scanf("%d",&T);
  while(T--)
  {
      int sum=0;
      memset(a,0,sizeof(a));
      scanf("%d",&n);
      for(int i=0;i<n;i++)
       {
           cin>> s;
           if(s[0]=='L')
            a[i]--;
           if(s[0]=='R')
            a[i]++;
            if(s[0]=='S')
           {
               cin>>c; //AS
               cin>>m;//數字 
               a[i]=a[m-1];//找到前面的數組m-1的值 
           }
       }
       for(int i=0;i<n;i++)
           sum+=a[i];
           printf("%d\n",sum);
  }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章