安徽科技學院2016-2017-1學期2013信息與計算科學12班期末測試_題解

2016-2017-1學期2013信息與計算科學12班<算法分析與設計>期末測試

Contest Link

Problem ID Title Source
1183 Problem A 公約數和公倍數 基礎
1268 Problem B 逆反A*B icpc4th@ahstu
1426 Problem C 子串和 NYOJ
1264 Problem D 圖書館佔位 icpc4th@ahstu
1527 Problem E 快看,有人撿到錢了!!! wwy
1528 Problem F 螞蟻 nyoj
1529 Problem G 尋找最大數 nyoj改編
1530 Problem H 神童的煩惱 nyoj改編
1531 Problem I Grasshopper Codeforces改編

Problem A 公約數和公倍數

Description

小明被一個問題給難住了,現在需要你幫幫忙。問題是:給出兩個整數,求出它們的最大公約數和最小公倍數。

Input

第一行輸入一個大於0的整數n(n<=20),示有n組測試數據隨後的n行輸入兩個整數i,j(i,j小於32767)。

Output

輸出每組測試數據的最大公約數和最小公倍數

Sample Input

3
6 6
12 11
33 22

Sample Output

6 6
1 132
11 66

題解:這道題屬於簡單題,下面直接給出代碼

#include <stdio.h>
int gcd(int a, int b)
{
    return b ? gcd(b, a%b) : a;
}
int main()
{
    int t, a, b;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d%d", &a, &b);
        printf("%d %d\n", gcd(a, b), a*b/gcd(a, b));
    }
    return 0;
}

Problem B 逆反A*B

Description

給定A B計算A*B的結果C,不過這裏面都要反過來啦!
舉例:52*52=526 因爲52表示25(逆反數)25*25=652,
A B 不超過10000

Input

輸入A,B

Output

計算A B的逆反數的積的逆反數C

Sample Input

52 52
30 30
1 1 

Sample Output

526
9
1

題解:這道題也是道簡單題,詳見代碼,關鍵寫一個逆反數的轉換函數即可

#include <stdio.h>
int f(int n,int a)
{
    return n?f(n/10,a*10+n%10):a;
}
int main()
{
    int a,b;
    while(~scanf("%d%d",&a,&b))
        printf("%d\n",f(f(a,0)*f(b,0),0));
    return 0;
}

Problem C 子串和

Description

給定一整型數列{a1,a2…,an},找出連續非空子串{ax,ax+1,…,ay},使得該子序列的和最大,其中,1<=x<=y<=n。

Input

第一行是一個整數N(N<=10)表示測試數據的組數)
每組測試數據的第一行是一個整數n表示序列中共有n個整數,隨後的一行裏有n個整數I(-100=

Output

對於每組測試數據輸出和最大的連續子串的和。

Sample Input

1
5
1 2 -1 3 -2

Sample Output

5

Hint

輸入數據很多,推薦使用scanf進行輸入

題解:經典算法,對數列進行一次掃描並求和,保存其thisSum,並更新最大和maxSum,若是當前和thisSum<0,則置thisSum=0從當前位置開始累加,因爲負數加上一個數肯定是會變小的,最終的maxSum就是最大值

#include <stdio.h>  
int main()  
{  
    int T, n, x;
    scanf("%d", &T);
    while(T--)
    {
        int thisSum=0, maxSum=0;
        scanf("%d", &n);
        for(int i=0; i<n; i++)  
        {  
            scanf("%d", &x);  
            thisSum += x;
            if(thisSum > maxSum)  
                maxSum = thisSum;  
            if(thisSum < 0)  
                thisSum = 0;
        }  
        printf("%d\n", maxSum);  
    }  
    return 0;  
}  
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int t = cin.nextInt();
        while (t-- > 0) {
            int n = cin.nextInt();
            int maxSum = 0, thisSum = 0;
            for (int i=0; i<n; i++) {
                int data = cin.nextInt();
                thisSum += data;
                if (thisSum > maxSum)
                    maxSum = thisSum;
                if (thisSum < 0)
                    thisSum = 0;
            }
            System.out.println(maxSum);
        }
        cin.close();
    }
}

Problem D 圖書館佔位

Description

圖書館佔位的很厲害,只要去晚了一會就沒有位置了。有些人佔着位置卻不來自習,這就造成了資源的浪費。現在我們的問題是一天當中有n個同學可能會來到同一個座位,假設上面有人則另外找座位,若沒有人,則就可以佔據此位置,直至你離開爲止。爲了最大化利用圖書館資源,我們要求的問題是一個位置最多能夠被幾個同學來用過。

Input

多組測試數據
第一行爲n個同學 (1 <=n<=10000)
接下來n行就是每個同學的進入圖書館的時間和離開圖書館的時間,爲了簡化問題,我們假設時間值爲整數。

Output

輸出一個座位最多被幾位同學佔據。

Sample Input

6
1 3
2 4
3 6
7 9
5 7
10 11

Sample Output

4

題解:此題用貪心法求解,首先對所有同學離開圖書館的先後進行排序,然後對此序列進行遍歷,只要離開圖書館的時間小於第二個同學進入圖書館的時間,這個位置可坐人數+1,遍歷完畢也即得到此位置最多可以容納的人數

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct A {
    int start, end;

    bool operator<(const A &a) const {
        return this->end < a.end;
    }
};

int main() {
    for (int n; cin >> n;) {
        vector<A> v(n);
        for (int i = 0; i < n; i++)
            cin >> v[i].start >> v[i].end;
        sort(v.begin(), v.end());
        int tot = 0, start = 0;
        for (vector<A>::iterator it = v.begin(); it != v.end(); ++it) {
            if (it->start >= start) {
                ++tot;
                start = it->end;
            }
        }
        cout << tot << endl;
    }
    return 0;
}

Problem E 快看,有人撿到錢了!!!

Description

老趙喜歡吃燒烤,在一次和同學們吃完燒烤回來的路上,老趙一不小心撿了一百塊,同學們強烈要求老趙買蛋糕慶祝,老趙爽快的扔了兩百給蛋糕店,讓他們做一個球形的大蛋糕。現在老趙拿起了刀叉準備和同學們瓜分這個蛋糕,一刀下去蛋糕成了兩塊,然後n個同學每人都來一刀。
現在老趙問同學們,n個人切完以後蛋糕最多有多少塊。(能ac的送thinkpaid)。

Input

多組輸入,每行一個整數n,n個同學

Output

對於每個整數n,輸出一個整數s(n個人切完蛋糕最多有s塊)

Sample Input

1
2

Sample Output

4
8

題解:這道題有一定難度,此題屬於平面分割空間問題,需要運用遞推關係,具體請查閱相關資料。
公式是f(n)=(n^3+5n)/6+1

#include <stdio.h>
#include <math.h>

int main()
{
    int n;
    while (~scanf("%d",&n)) {
        n++;
        printf("%d\n", (n*n*n+5*n)/6+1);
    }
    return 0;
}

Problem F 螞蟻

Description

n只螞蟻義每秒1cm的速度在長爲Lcm的杆子上爬行。當螞蟻爬到杆子的端點就會掉下去。由於杆子太細,兩隻螞蟻相遇時,他們不能交錯通過,只能各反向回去。對於每隻螞蟻,我們知道它距離杆子左端的距離xi,但不知道它當時的朝向,計算所有螞蟻落下杆子的最短時間和最長時間。
1<=L<=10^6
1<=n<=10^6;
0<=xi<=L;

Input

多組輸入,第一行L和n,接下來n個xi(L爲杆子的長度,n只螞蟻,及每隻螞蟻距離杆子左端的距離xi)

Output

輸出螞蟻落下杆子的最短時間和最長時間

Sample Input

10 3
2 6 7

Sample Output

4 8

題解:這道題只要考慮清楚後其實也很好解,不需要考慮掉頭情況,因爲螞蟻速度一樣,即是說螞蟻掉頭對此題不產生影響。也可以這樣理解,在遠處觀察這些螞蟻的運動,一羣螞蟻運動時,因爲速度是一樣的,所以當螞蟻碰撞而掉頭時,看上去和兩個點“對穿而過”沒有任何區別,這樣,不論最長時間還是最短時間,都只要對每隻螞蟻檢查一次就好了,這是O(n)時間的算法。於是問題得解。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
    int L, n, minT, maxT, a;
    while (~scanf("%d%d", &L, &n))
    {
        minT = 0; maxT = 0;
        for (int i=0; i<n; i++) {
            scanf("%d", &a);
            minT = max(minT, min(a, L-a));
            maxT = max(maxT, max(a, L-a));
        }
        printf("%d %d\n", minT, maxT);
    }
    return 0;
}

Problem G 尋找最大數

Description

給出一個整數n每次可以移動相鄰數位上的數字,最多移動k次,得到一個新的整數,求這個新的整數的最大值是多少。

Input

多組測試數據。
每組測試數據佔一行,每行有兩個數N和K (1 ≤ N≤ 10^18; 0 ≤ K ≤ 100).

Output

每組測試數據的輸出佔一行,輸出移動後得到的新的整數的最大值。

Sample Input

1990 1
100 0
9090000078001234 6

Sample Output

9190
100
9907000008001234

題解:一個數交換每次相鄰兩位數,因爲高位數字越大數字結果就越大。可以交換k次,所以可以依次在當前位置到當前的第k位找到最大數並交換到當前位置,每交換一次k–
重複上述步驟,直到k=0結束,這樣得到數字也即使最大數

#include <stdio.h>
#include <string.h>
char a[100], max;
int k, i, j, index;

void solve()
{
    int len = strlen(a);
    for (i=0; i<len && k; i++) {
        index = i; max = a[i];
        for (j=i+1; j<len && j<=i+k; j++) {
            if (max < a[j]) {
                index = j;
                max = a[j];
            }
        }
        for (j=index; j>i; j--) {
            a[j] = a[j-1];
            k--;
        }
        a[i] = max;
    }
    puts(a);
}

int main()
{
    while (~scanf("%s %d", a, &k))
    {
        solve();
    }
    return 0;
}

Problem H 神童的煩惱

Description

數學神童小明終於把0到100000000的Fibonacci數列(f[0]=0,f[1]=1;f[i] = f[i-1]+f=2”>i-2)的值全部給背了下來。
接下來,CodeStar決定要考考他,於是每問他一個數字,他就要把答案說出來,不過有的數字太長了。所以規定超過4位的只要說出前4位(高4位)就可以了,可是CodeStar自己又記不住。於是他決定編寫一個程序來測驗小明說的是否正確。

Input

輸入若干數字n(0 <= n <= 100000000),每個數字一行。讀到文件尾結束。

Output

輸出f[n]的前4個數字(若不足4個數字,就全部輸出)。

Sample Input

0
1
2
3
4
5
35
36
37
38
39
40

Sample Output

0
1
1
2
3
5
9227
1493
2415
3908
6324
1023

題解:這道題需要用到斐波那契數列的通項公式
斐波拉契數列通項公式
log10f(n)=n*log10((1+√5)/2)-log10√5+log10(1-((1-√5)/(1+√5))n) 後一部分隨着n的增大快速的就趨近餘0,是高階無窮小. 可以忽略。所以有log10f(n) ≈n*log10((1+√5)/2)-log10√5
此題要求斐波拉契前4位,由此可以得出pow(10,log10f(n)+3-整數部分),在對其取整即爲結果。需要注意的是斐波拉契前較小項因爲浮點誤差所以應該事先求出

#include <stdio.h>
int main()
{
    int n, i;
    int fib[21]={0, 1};
    for (i=2; i<=20; i++)
        fib[i] = fib[i-1]+fib[i-2];

    while (~scanf("%d", &n))
    {
        if (n <= 20)
            printf("%d\n", fib[n]);
        else {
            double f=n*log10((sqrt(5)+1)*.5)-log10(sqrt(5));
            f = f+3-floor(f);
            printf("%d\n", (int)pow(10, f));
        }
    }
    return 0;
}

Problem I Grasshopper

Description

One day, the Grasshopper was jumping on the lawn and found a piece of paper with a string. Grasshopper became interested what is the minimum jump ability he should have in order to be able to reach the far end of the string, jumping only on vowels of the English alphabet. Jump ability is the maximum possible length of his jump.

Formally, consider that at the begginning the Grasshopper is located directly in front of the leftmost character of the string. His goal is to reach the position right after the rightmost character of the string. In one jump the Grasshopper could jump to the right any distance from 1 to the value of his jump ability.

算法設計與分析Grasshopper

The picture corresponds to the first example.

The following letters are vowels: ‘A’, ‘E’, ‘I’, ‘O’, ‘U’ and ‘Y’.

Input

Input contains multiple test cases.The first line contains non-empty string consisting of capital English letters. It is guaranteed that the length of the string does not exceed 100.

Output

Print single integer a — the minimum jump ability of the Grasshopper (in the number of symbols) that is needed to overcome the given string, jumping only on vowels.

Sample Input

ABABBBACFEYUKOTT
AAA

Sample Output

4
1

題解:這道題是比較容易的一道題,主要是英語題於是大家都沒有做了,思路很簡單,找到一個序列中跨越元音字母(’A’, ‘E’, ‘I’, ‘O’, ‘U’, ‘Y’)的最大長度,看圖例就能很好明白,直接給出代碼

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>

using namespace std;

bool is(char c)
{
    char a[6] = {'A', 'E', 'I', 'O', 'U', 'Y'};
    for (int i=0; i<6; i++)
        if (a[i] == c)
            return true;
    return false;
}

int main()
{
    char s[1000];
    while (~scanf("%s", s))
    {
        int m = 1, mx = 0;
        for (int i=0; i<strlen(s); i++) {
            if (is(s[i])) {
                m = 1;
            }else m++;
            if (mx < m)
                mx = m;
        }
        printf("%d\n", mx);
    }
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        while (cin.hasNext()) {
            char[] a = cin.next().toCharArray();
            int len = 1, max = 1;
            for (int i=0; i<a.length; i++) {
                if (f(a[i])) {
                    len = 1;
                }else
                    len++;
                if (len > max)
                    max = len;
            }
            System.out.println(max);
        }
        cin.close();
    }

    private static boolean f(char c) {
        char a[] = {'A', 'E', 'I', 'O', 'U', 'Y'};
        for (int i=0; i<a.length; i++)
            if (a[i] == c)
                return true;
        return false;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章