HDOJ

#1003 Max Sum

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1003
解析鏈接:https://my.oschina.net/itblog/blog/267860

算法一(窮竭算法)

#include <cstdio>
#include <cstring>

const int MAX_N = 100000;
int seq[MAX_N], T, kase = 0, first = true;

int main() {
    void resolve();
    scanf("%d", &T);
    resolve();
    return 0;
}

void resolve() {
    while (T--) {
        memset(seq, 0, sizeof(seq));

        int N, max_sum = 0, s = 0, t = 0;
        scanf("%d", &N);
        for (int i = 0; i < N; ++i)
            scanf("%d", &seq[i]);
        for (int i = 0; i < N; ++i) {
            for (int j = i; j < N; ++j) {
                int sum = 0;
                for (int k = i; k <= j; ++k)
                    sum += seq[k];
                if (sum > max_sum) {
                    max_sum = sum;
                    s = i;
                    t = j;
                }
            }
        }
        if (first)
            first = false;
        else
            printf("\n");
        printf("Case %d:\n", ++kase);
        printf("%d %d %d\n", max_sum, s + 1, t + 1);
    }
}

此算法比較簡單,但時間複雜度爲 O(n3)\ O(n^3)。提交會顯示超時。

算法二

for (int i = 0; i < N; ++i) {
    int sum = 0;
    for (int j = i; j < N; ++j) {
        sum += seq[j];
        if (sum > max_sum) {
            max_sum = sum;
            s = i;
            t = j;
        }
    }
}

顯然,此算法時間複雜度爲 O(n2)\ O(n^2)。但提交時仍然超時。

算法三

#include <cstdio>
#include <cstring>

const int MAX_N = 100000;
int seq[MAX_N], T, kase = 0, first = true;

int main() {
    void resolve();
    scanf("%d", &T);
    resolve();
    return 0;
}

void resolve() {
    while (T--) {
        memset(seq, 0, sizeof(seq));

        int N, max_sum = 0, this_sum = 0, s = 0, t = 0;
        scanf("%d", &N);
        for (int i = 0; i < N; ++i)
            scanf("%d", &seq[i]);

        // 如果全爲負數
        bool all_negative = true;
        for (int i = 0; i < N; ++i) {
            if (seq[i] >= 0) all_negative = false;
        }
        if (all_negative) {
            max_sum = seq[0];
            s = 0, t = 0;
            for (int i = 1; i < N; ++i) {
                if (seq[i] > max_sum) {
                    max_sum = seq[i];
                    s = i, t = i;
                }
            }
        } else
            // 不全爲負數
            for (int i = 0, j = 0; j < N; ++j) {
                this_sum += seq[j];
                if (this_sum > max_sum) {
                    max_sum = this_sum;
                    s = i;
                    t = j;
                } else if (this_sum < 0) {
                    this_sum = 0;
                    i = j + 1;
                }
            }
        if (first)
            first = false;
        else
            printf("\n");
        printf("Case %d:\n", ++kase);
        printf("%d %d %d\n", max_sum, s + 1, t + 1);
    }
}

#1004 Let the Balloon Rise

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1004

#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
const int MAX_N = 1005;
string colors[MAX_N];
typedef pair<string, int> BALLOON;
BALLOON B[MAX_N];

int main()
{
    void resolve();
    resolve();
    return 0;
}

void resolve()
{
    int N;

    while(cin>>N && N != 0)
    {
        int color_count = 0;
        for(int i = 0; i<N; i++)
        {
            cin>>colors[i];
            string color = colors[i];
            int j;
            for(j = 0; j<color_count; j++)
            {
                if(color == B[j].first)
                {
                    B[j].second++;
                    break;
                }
            }
            if(j>= color_count)
            {
                BALLOON b(color, 1);
                B[color_count++] = b;
            }
        }

        BALLOON popular = B[0];
        for(int i = 1; i<color_count; i++)
        {
            BALLOON b = B[i];
            if(b.second>popular.second)
            {
                popular = b;
            }
        }
        cout<<popular.first<<endl;
    }
}


#1005 Number Sequence

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1005

#include <cstdio>
#include <cstring>
const int MAX_N = 1000;
int F[MAX_N], A, B, n;

int main(){
	void resolve();
	resolve();
	return 0;
} 

void resolve(){
	int initF();
	while(scanf("%d %d %d", &A, &B, &n) !=EOF){
		// 終止條件
		if(A == 0 && B == 0 && n ==0 ) break;
		
		memset(F, -1 , sizeof(F));
		int cycle = initF();
		int res = F[n % cycle];
		printf("%d\n", res);
	}
}

// 返回循環週期
int initF(){
	F[1] = 1,F[2] = 1;
	int i, cycle;
	for(i = 3;i<MAX_N;i++){
		F[i] = ((A *F[i-1] + B*F[i-2]) % 7);
		if(F[i] == 1 && F[i-1] == 1){
			/* ① */
			break;
		}
	}
	cycle = i-2; /* ② */
	F[0] = F[cycle];
	return cycle;
}

上面這段代碼比較神祕的地方在於,如果把②處的這一行移到①處,邏輯上沒有任何問題,本地也能跑通,但提交的時候會報“除0”錯誤。有時候不得不說,編程是一種玄學。

#1008 Elevator

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1008

#include<cstdio>
const int MAX_N = 100;
int a[MAX_N];
int N;
int main()
{
    void resolve();
    resolve();
    return 0;
}

void resolve()
{
    while(scanf("%d", &N) == 1 && N !=0)
    {
        int t = 0, current = 0;
        for(int i = 0; i< N; i++)
        {
            scanf("%d", &a[i]);
        }
        t = N * 5;
        for(int i = 0; i< N; i++)
        {
            int next = a[i];
            if(next > current)
            {
                t += ((next-current) * 6);
            }
            else if(next < current)
            {
                t += ((current-next) * 4);
            }
            current = next;
        }
        printf("%d\n", t);
    }
}

這道題有一點沒有講明白的是,如果連續多次是同一樓層,那麼每一樓層是不是仍然要加5秒。但實際在提交的時候,如果你不加,是不通過的。

#1012 u Calculate e

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1012

#include <cstdio>

int main(){
    void resolve();
    resolve();
    return 0;
}

void resolve(){
    int fac(int);
    int n = 9;
    printf("n e\n- -----------\n0 1\n1 2\n2 2.5\n");
    for(int i= 3;i<=9 ;i++){
        printf("%d ", i);
        double e = 0;
        for(int j = 0;j<=i;j++){
            e+=(1.0 / fac(j));
        }
        printf("%.9f\n", e);
    }
}

int fac(int n){
    if(n == 0) return 1;
    return n * fac(n-1);
}

這道題坑的地方在於只有前面三個不需要後面補0,而後面的全部都是小數點後9位。所以把前三個單獨輸出。

#1013 Digital Roots

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1013

#include <cstdio>
#include <cstring>
const int MAX_N = 1000;
char n[MAX_N];
void resolve();
int main()
{
    resolve();
    return 0;
}

void resolve()
{
    int getRoot(int);

    while(scanf("%s", n)!=EOF)
    {
        int len = strlen(n);
        if(len == 1 && n[0]=='0')
            break;

        int sum = 0;
        for(int i = 0; i<len; i++)
        {
            sum+=n[i]-'0';
        }
        int root = getRoot(sum);
        printf("%d\n", root);
    }
}

int getRoot(int n)
{
    int sum = 0;
    while(n!=0)
    {
        sum+=n%10;
        n /= 10;
    }
    if(sum<10)
        return sum;
    else
        return getRoot(sum);
}

#1015 Safecracker

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1015

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int MAX_N = 13;
long long target;
char letter[MAX_N];

int main() {
    void resolve();
    resolve();
    return 0;
}

bool compare(int a, int b) {
    return a > b;
}

void resolve() {
    while (scanf("%lld %s", &target, letter)) {
        // 終止條件
        if (target == 0 && strcmp(letter, "END") == 0)break;

        int len = strlen(letter);

        sort(letter, letter + len, compare);
        bool ok = false;

        for (int i = 0; i < len; ++i) {
            for (int j = 0; j < len; ++j) {
                if (j == i) continue;
                for (int k = 0; k < len; ++k) {
                    if (k == j || k == i) continue;
                    for (int l = 0; l < len; ++l) {
                        if (l == i || l == j || l == k) continue;
                        for (int m = 0; m < len; ++m) {
                            if (m == i || m == j || m == k || m == l) continue;

                            int v = letter[i] - 'A' + 1;
                            int w = letter[j] - 'A' + 1;
                            int x = letter[k] - 'A' + 1;
                            int y = letter[l] - 'A' + 1;
                            int z = letter[m] - 'A' + 1;
                            long long res = (long long) (v - w * w + x * x * x - y * y * y * y + z * z * z * z * z);
                            if (target == res) {
                                printf("%c%c%c%c%c\n", letter[i], letter[j], letter[k], letter[l], letter[m]);
                                ok = true;
                                break;
                            }
                        }
                        if (ok) break;
                    }
                    if (ok) true;
                }
                if (ok) true;
            }
            if (ok) true;
        }
        if (!ok) printf("no solution\n");
    }
}

首先要降序排序。注意,這裏不能使用pow函數求次方,會出現精度問題。還有,這道題沒有說明白一點,就是各個字母不能重複出現。

#1017 A Mathematical Curiosity

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1017

#include <cstdio>
#include <cmath>

int N;

void resolve();

int main() {
    scanf("%d", &N);
    resolve();
    return 0;
}

void resolve() {
    bool first = true;
    while (N--) {
        int n, m;
        int kase = 0;
        if (first)
            first = false;
        else
            printf("\n");
        while (scanf("%d%d", &n, &m) == 2) {
            if (!n && !m)break;
            int count = 0;
            for (int a = 1; a < n; ++a) {
                for (int b = a + 1; b < n; ++b) {
                    int Z = a * a + b * b + m;
                    int M = a * b;
                    if (Z % M == 0)
                        count++;
                }
            }
            printf("Case %d: %d\n", ++kase, count);
        }
    }
}

#1018 Big Number

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1018
解析鏈接:https://blog.csdn.net/courtneygeng/article/details/9897149

#include <cstdio>
#include <cmath>

void resolve();

int main() {
    resolve();
    return 0;
}

void resolve() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        int num;
        scanf("%d", &num);
        double sum = 0;
        for (int j = 1; j <= num; ++j) {
            sum += log10(j);
        }
        int res = (int) sum + 1;
        printf("%d\n", res);
    }
}

任意一個正整數a的位數等於log10a+1\lfloor log_{10}a \rfloor + 1。任意階乘A=n!=123nA=n!=1 \cdot 2 \cdot 3 \cdot \cdots \cdot n,其位數爲log101+log102+log103++log10n+1\lfloor log_{10}1 + log_{10}2 + log_{10}3 + \cdots + log_{10}n\rfloor + 1

#1019 Least Common Multiple

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1019

#include <cstdio>
#include <iostream>

using namespace std;

int N;
const int MAX_M = 10000;
int nums[MAX_M];

void resolve();

int gcd(int, int);

int lcm(int, int);

int main() {
    scanf("%d", &N);
    resolve();
    return 0;
}

void resolve() {
    while (N--) {
        int m;
        scanf("%d", &m);
        for (int i = 0; i < m; ++i)
            scanf("%d", &nums[i]);
        int a = nums[0];
        for (int j = 1; j < m; ++j) {
            int LCM = lcm(a, nums[j]);
            a = LCM;
        }
        cout << a << endl;
    }
}

int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

int lcm(int a, int b) {
    if (a < b) {
        int tmp = a;
        a = b;
        b = tmp;
    }
    return a / gcd(a, b) * b;
}

#1021 Fibonacci Again

#include <cstdio>
#include <iostream>

using namespace std;

void resolve();

int main() {
    resolve();
    return 0;
}

void resolve() {
    int n;
    while (scanf("%d", &n) != EOF) {
        if (n % 4 == 2)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}

#1037 Keep on Truckin’

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1037

#include <cstdio>

int set[3];

int main() {
    void resolve();
    for (int i = 0; i < 3; ++i) {
        scanf("%d", &set[i]);
    }
    resolve();
    return 0;
}

void resolve() {
    bool crash = false;
    for (int i = 0; i < 3; ++i) {
        if (set[i] <= 168) {
            crash = true;
            printf("CRASH %d\n", set[i]);
            break;
        }
    }
    if (!crash) printf("NO CRASH\n");
}

#1342 Lotto

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1342
解析鏈接:https://blog.csdn.net/pengwill97/article/details/54850852

#include <cstdio>

const int MAX_N = 13;
int ans[6], S[MAX_N], k;

int main() {
    void resolve();
    resolve();
    return 0;
}

void resolve() {
    void dfs(int, int);
    bool first = true;
    while (scanf("%d", &k) && k != 0) {
        for (int i = 0; i < k; ++i) {
            scanf("%d", &S[i]);
        }
        if (first)first = false;
        else printf("\n");

        dfs(0, 0);
    }
}

void dfs(int i, int j) { // i表示ans數組的索引,j表示S數組的索引
    void print_ans();
    if (i >= 6) {
        print_ans();
        return;
    }
    if (j >= k) return;
    ans[i] = S[j];
    dfs(i + 1, j + 1);
    dfs(i, j + 1);
}

void print_ans() {
    printf("%d", ans[0]);
    for (int l = 1; l < 6; ++l) {
        printf(" %d", ans[l]);
    }
    printf("\n");
}

#1049 Climbing Worm

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1049

#include <cstdio>

int n, u, d;

int main() {
    void resolve();

    resolve();
    return 0;
}

void resolve() {
    while (scanf("%d%d%d", &n, &u, &d)) {
        if (!n && !u && !d) break;
        int cur_height = 0, time = 0;
        bool climb = true;
        while (cur_height < n) {
            if (climb)
                cur_height += u;
            else
                cur_height -= d;
            climb = !climb;
            time++;
        }
        printf("%d\n", time);
    }
}

#1089 A+B for Input-Output Practice (I)

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1089

#include <cstdio>

int main() {
    void resolve();

    resolve();
}

void resolve() {
    int a, b;
    while (scanf("%d%d", &a, &b) != EOF) {
        printf("%d\n", a + b);
    }
}

#1090 A+B for Input-Output Practice (II)

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1090

#include <cstdio>

int main() {
    void resolve();

    resolve();
}

void resolve() {
    int a, b, n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d%d", &a, &b);
        printf("%d\n", a + b);
    }
}

#1091 A+B for Input-Output Practice (III)

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1091

#include <cstdio>

int main() {
    void resolve();

    resolve();
}

void resolve() {
    int a, b;
    while (scanf("%d%d", &a, &b) != EOF) {
        if (!a && !b) break;
        printf("%d\n", a + b);
    }
}

#1092 A+B for Input-Output Practice (IV)

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1092

#include <cstdio>

int main() {
    void resolve();

    resolve();
    return 0;
}

void resolve() {
    int n, sum, tmp;
    while (scanf("%d", &n)) {
        if (!n) break;
        sum = 0;
        for (int i = 0; i < n; ++i) {
            scanf("%d", &tmp);
            sum += tmp;
        }
        printf("%d\n", sum);
    }
}

#1093 A+B for Input-Output Practice (V)

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1093

#include <cstdio>

int N;

int main() {
    void resolve();
    resolve();
    return 0;
}

void resolve() {
    scanf("%d", &N);
    for (int i = 0; i < N; ++i) {
        int M, sum = 0, tmp;
        scanf("%d", &M);
        for (int j = 0; j < M; ++j) {
            scanf("%d", &tmp);
            sum += tmp;
        }
        printf("%d\n", sum);
    }
}

#1094 A+B for Input-Output Practice (VI)

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1094

#include <cstdio>

int main() {
    void resolve();
    resolve();
    return 0;
}

void resolve() {
    int N, sum, tmp;
    while (scanf("%d", &N) != EOF) {
        sum = 0;
        for (int i = 0; i < N; ++i) {
            scanf("%d", &tmp);
            sum += tmp;
        }
        printf("%d\n", sum);
    }
}

#1095 A+B for Input-Output Practice (VII)

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1095

#include <cstdio>

int main() {
    void resolve();
    resolve();
    return 0;
}

void resolve() {
    int a, b;
    while (scanf("%d%d", &a, &b) != EOF) {
        printf("%d\n\n", a + b);
    }
}

#1096 A+B for Input-Output Practice (VIII)

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1096

#include <cstdio>

int main() {
    void resolve();
    resolve();
    return 0;
}

void resolve() {
    int N, M, sum, tmp;
    bool first = true;
    scanf("%d", &N);
    for (int i = 0; i < N; ++i) {
        scanf("%d", &M);
        sum = 0;
        for (int j = 0; j < M; ++j) {
            scanf("%d", &tmp);
            sum += tmp;
        }
        if (first) {
            first = false;
        } else {
            printf("\n");
        }
        printf("%d\n", sum);
    }
}

#1097 A hard puzzle

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1097

#include <cstdio>
#include <cstring>

int main() {
    void resolve();
    resolve();
    return 0;
}

void resolve() {
    long long a, b;
    int digit[10]; // 存放個位數的數組,最多不超過10個:0~9
    while (scanf("%lld%lld", &a, &b) != EOF) {
        int last = (int) a % 10; // a的個位數
        int res = 1;
        memset(digit, -1, sizeof(digit));
        int digit_len = 0; // digit數組實際的元素個數
        for (int i = 0; i < b; ++i) {
            res *= last;
            res %= 10;

            // 查找新的個位數在不在digit數組中
            bool exit = false;
            for (int j = 0; j < digit_len; ++j) {
                if (res == digit[j]) { // 如果某個數已經在digit中,說明已經產生了一個循環,則退出
                    exit = true;
                    break;
                }
            }
            if (!exit) digit[digit_len++] = res; // 某個數不在digit中,則加入digit中
            if (exit)break;
        }

        int pos = (int) (b % digit_len);
        if (pos == 0) pos = digit_len - 1;
        else pos -= 1;
        printf("%d\n", digit[pos]);
    }
}

#1098 Ignatius’s puzzle

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1098

#include <cstdio>

int main() {
    void resolve();
    resolve();
    return 0;
}

void resolve() {
    int k;
    while (scanf("%d", &k) != EOF) {
        int a;
        for (a = 1; a < 10000; ++a) {
            if ((18 + k * a) % 65 == 0) {
                printf("%d\n", a);
                break;
            }
        }
        if (a >= 10000) {
            printf("no\n");
        }
    }
}

由於對於任何的x都成立,取x=1,得 18+ka 。即只要(18+ka)%65 == 0即可。詳細的證明可參考:https://blog.csdn.net/u014355480/article/details/44248493。在這裏,由題意可知k<10000,而a與k的身份相同,均爲因式,可認爲a<10000,故for循環的條件是a < 10000 。

#1099 Lottery

原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1099

#include <cstdio>

typedef long long LL;

LL gcd(LL, LL);

LL lcm(LL, LL);

int digits(LL);

int main() {
    void resolve();
    resolve();
    return 0;
}

void resolve() {
    int n;
    while (scanf("%d", &n) != EOF) {
        LL z = 1, m = 1, integer = 0; // z分子, m分母, integer表示帶分數的整數部分
        LL g; // 求最大公約數的臨時變量
        for (int i = 2; i <= n; ++i) {
            LL old_m = m;
            m = lcm(m, i); // 分母
            z = z * (m / old_m) + (m / i); // 分子
        }
        z *= n;
        g = gcd(m, z);
        z /= g;
        m /= g;
        if (z % m == 0) { // 能整除
            printf("%lld\n", z / m);
        } else { // 不能整除,帶分數
            integer = z / m;
            z %= m;

            for (int i = 0; i < digits(integer); ++i)
                printf(" ");
            printf(" %lld\n", z);
            printf("%lld ", integer);
            for (int i = 0; i < digits(m); ++i)
                printf("-");
            printf("\n");
            for (int i = 0; i < digits(integer); ++i)
                printf(" ");
            printf(" %lld\n", m);
        }
    }
}

// 最大公約數
LL gcd(LL a, LL b) {
    if (a == 0) return b;
    return gcd(b % a, a);
}

// 最小公倍數
LL lcm(LL a, LL b) {
    return a * b / gcd(a, b);
}

// 求一個數字的位數
int digits(LL number) {
    int i = 0;
    while (number > 0) {
        number /= 10;
        i++;
    }
    return i;
}

問題轉化爲求n(11+12+13++1n1+1n) n(\frac{1}{1}+\frac{1}{2}+\frac{1}{3}+\cdots+\frac{1}{n-1}+\frac{1}{n})
要注意,這裏求最大公約數要用輾轉相除法,直接使用遍歷求最大公約數會超時。

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