原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003
解析链接:https://my.oschina.net/itblog/blog/267860
算法一(穷竭算法)
#include
#include
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 ( n 3 ) \ O(n^3) O(n3)。提交会显示超时。
算法二
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 ( n 2 ) \ O(n^2) O(n2)。但提交时仍然超时。
算法三
#include
#include
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);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1004
#include
#include
#include
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;
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1005
#include
#include
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”错误。有时候不得不说,编程是一种玄学。
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1008
#include
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秒。但实际在提交的时候,如果你不加,是不通过的。
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1012
#include
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位。所以把前三个单独输出。
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1013
#include
#include
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);
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1015
#include
#include
#include
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函数求次方,会出现精度问题。还有,这道题没有说明白一点,就是各个字母不能重复出现。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1017
#include
#include
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);
}
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1018
解析链接:https://blog.csdn.net/courtneygeng/article/details/9897149
#include
#include
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的位数等于 ⌊ l o g 10 a ⌋ + 1 \lfloor log_{10}a \rfloor + 1 ⌊log10a⌋+1。任意阶乘 A = n ! = 1 ⋅ 2 ⋅ 3 ⋅ ⋯ ⋅ n A=n!=1 \cdot 2 \cdot 3 \cdot \cdots \cdot n A=n!=1⋅2⋅3⋅⋯⋅n,其位数为 ⌊ l o g 10 1 + l o g 10 2 + l o g 10 3 + ⋯ + l o g 10 n ⌋ + 1 \lfloor log_{10}1 + log_{10}2 + log_{10}3 + \cdots + log_{10}n\rfloor + 1 ⌊log101+log102+log103+⋯+log10n⌋+1。
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1019
#include
#include
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;
}
#include
#include
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;
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1037
#include
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");
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1342
解析链接:https://blog.csdn.net/pengwill97/article/details/54850852
#include
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");
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1049
#include
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);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1089
#include
int main() {
void resolve();
resolve();
}
void resolve() {
int a, b;
while (scanf("%d%d", &a, &b) != EOF) {
printf("%d\n", a + b);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1090
#include
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);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1091
#include
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);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1092
#include
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);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1093
#include
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);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1094
#include
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);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1095
#include
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);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1096
#include
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);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1097
#include
#include
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]);
}
}
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1098
#include
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 。
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1099
#include
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 ( 1 1 + 1 2 + 1 3 + ⋯ + 1 n − 1 + 1 n ) n(\frac{1}{1}+\frac{1}{2}+\frac{1}{3}+\cdots+\frac{1}{n-1}+\frac{1}{n}) n(11+21+31+⋯+n−11+n1)
要注意,这里求最大公约数要用辗转相除法,直接使用遍历求最大公约数会超时。