1. http://acm.hdu.edu.cn/showproblem.php?pid=1000 最简单那种A + B,一般OJ上都会有这道题目,只要学过c语言,都应该会写的,就不说了。
2.http://acm.hdu.edu.cn/showproblem.php?pid=1002 简单的高精度加法问题,注意前导零和进位处理就没什么问题了
3.http://acm.hdu.edu.cn/showproblem.php?pid=1228 字符串简单处理,用c++里面的函数,还是很方便的。感觉最有价值的一个题目,因为学会了用这个函数,以后从句子里提取单个单词就方便多了
1 #include <sstream> // 需要的头文件 2 #include <string.h> 3 #include <stdio.h> 4 #include <string> 5 #include <iostream> 6 #include <map> 7 8 using namespace std; 9 10 map<string,int>m; // map 方便字符串与数字的对应 11 int main() 12 { 13 m["zero"] = 0; 14 m["one"] = 1; 15 m["two"] = 2; 16 m["three"] = 3; 17 m["four"] = 4; 18 m["five"] = 5; 19 m["six"] = 6; 20 m["seven"] = 7; 21 m["eight"] = 8; 22 m["nine"] = 9; 23 char line[100]; 24 //freopen("data.txt","r",stdin); 25 while(gets(line)) 26 { 27 if(!strcmp(line,"zero + zero =")) break; 28 int a = 0; 29 int b = 0; 30 istringstream s(line); // 库函数 31 while(s>>line) // 从 s(即输入的原字符串) 字符串里面提取单个单词,以空格作为分界符 32 { 33 if(!strcmp(line,"+")) break; 34 a = a * 10 + m[line]; 35 } 36 while(s >> line) 37 { 38 if(!strcmp(line,"=")) break; 39 b = b * 10 + m[line]; 40 } 41 cout<<a + b<<endl; 42 } 43 return 0; 44 }
4.http://acm.hdu.edu.cn/showproblem.php?pid=1866 题目的意思是说:有多组输入,每组输入里给n个矩形的对角线的两个点的二维坐标,让你计算在不重复计算重叠的情况下矩形的总面积。感觉以前也没怎么做过这种面积的并的题目,也没有用这种方法做过。
思路:找出给出的每个矩形的最大最小 x 和 y ,双重循环把每个矩形分割以1单位为边长的正方形,用二维数组记录被分割的每个单位面积是否被计算过
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #define N 1100 #define _clr(a,val) (memset(a,val,sizeof(a))) using namespace std; int v[N][N]; char str[N]; int d[4]; int main() { int i,j; int num; int min_x,min_y,max_x,max_y; int k; //freopen("data.txt","r",stdin); while(gets(str)) { _clr(v,0); int len = strlen(str); num = 0; int are = 0; for(i = 0; i < len; i++) { if(isdigit(str[i])) { int tem = 0; while(isdigit(str[i])) { tem = tem * 10 + (str[i - 1] - '0'); i++; } d[num++] = tem; i--; } if(num == 4) { num = 0; max_x = max(d[0],d[2]); // 找最值 min_x = min(d[0],d[2]); max_y = max(d[1],d[3]); min_y = min(d[1],d[3]); for(j = min_x + 1; j <= max_x; j++) // 分割计算面积 { for(k = min_y + 1; k <= max_y; k++) { if(v[j][k] == 0) {v[j][k] = 1; are++;} } } } } cout<<are<<endl; } return 0; }
5.http://acm.hdu.edu.cn/showproblem.php?pid=1867 题目意思是给两个字符串,看他们的首尾是否有公共的子串(不论是谁在前在后),如果有,则要覆盖掉一个公共的子串,把这两个字符串连成一个,连接的规则是:首先看怎么连可以更短,如果不论是哪个字符串在前,长度都是一样的,那么这时要看这两个字符串字典序小的在前边。
思路:很简单的kmp使用。用kmp算法分别算出每个字符串的next值,然后再分别计算第一个在前,和第二个在前这两种情况下消去的子串长度,再判断
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <math.h> 5 #include <algorithm> 6 #define N 100001 7 #define _clr(a,val) (memset(a,val,sizeof(a))) 8 9 using namespace std; 10 11 char str[N],sbr[N]; 12 int next[N]; 13 void get_next(char s[]) 14 { 15 int i,j; 16 int len = strlen(s); 17 i = 0; j = -1; 18 next[0] = -1; 19 while(i < len) 20 { 21 if(s[i] == s[j] || j == -1) 22 next[++i] = ++j; 23 else j = next[j]; 24 } 25 } 26 int kmp(char a[],char b[]) 27 { 28 int i = 0,j = 0; 29 int len = strlen(a); 30 get_next(b); 31 while(i < len) 32 { 33 if(a[i] == b[j] || j == -1) 34 { 35 i++;j++; 36 } 37 else j = next[j]; 38 } 39 return j; 40 } 41 int main() 42 { 43 int flag1,flag2; 44 //freopen("data.txt","r",stdin); 45 while(cin>>str>>sbr) 46 { 47 _clr(next,0); 48 flag1 = kmp(str,sbr); // 计算两种情况 49 flag2 = kmp(sbr,str); 50 // 判断 51 if(flag1 == flag2) 52 { 53 if(strcmp(str,sbr) < 0) 54 { 55 printf("%s%s\n",str,sbr + flag1); 56 } 57 else printf("%s%s\n",sbr,str + flag1); 58 } 59 else if(flag1 < flag2) 60 { 61 printf("%s%s\n",sbr,str + flag2); 62 } 63 else printf("%s%s\n",str,sbr + flag1); 64 } 65 return 0; 66 }
6.http://acm.hdu.edu.cn/showproblem.php?pid=2057 题目是给两个十六进制的数,计算 a + b,这个直接用十六进制输入输出就可以了,不过要注意,因为题目说了a b的长度对大是15位,所以要用 long long 或 __int64,还有就是有可能 a + b 小于零这种情况,注意处理
1 #include <stdio.h> 2 #include <iostream> 3 #include <stdlib.h> 4 5 using namespace std; 6 7 int main() 8 { 9 long long a,b; 10 //freopen("data.txt","r",stdin); 11 while(scanf("%I64x%I64x",&a,&b) != EOF) 12 { 13 if(a + b < 0) 14 { 15 printf("-%I64X\n",-a - b); 16 } 17 else 18 printf("%I64X\n",a + b); 19 } 20 return 0; 21 }
7.http://acm.hdu.edu.cn/showproblem.php?pid=2101,跟第一个 a + b是一样的就不说了
8.http://acm.hdu.edu.cn/showproblem.php?pid=2524 题目意思:给出一个矩形的长和高,问这个矩形里一共有多少个矩形。
思路:由这n * m个小矩形组成的矩形里,长是从1 到 n,宽是从 1 到 m ,就是求两个等差数列的和,因为矩形的组成是一个组合,所以再乘出来,即 NUM = ( ( 1 + n ) * n / 2 ) * ( ( 1 + m ) * m / 2);
9.http://acm.hdu.edu.cn/showproblem.php?pid=3818 题目是:给出T组测试样例,每个样例有两行输入,首先是一个n,然后n个数,代表的是第几个斐波那契数,然后把这两行的所有斐波那契数求和,看可以再用那几个斐波那契表示这个和,输出的第一个数是用的斐波那契数列的总个数,然后是第几个斐波那契数列
思路:不断转化。因为给出的是斐波那契数的下标,如果 a - b == 1,那么 f(a) = f(b) + f(b - 1),同样,如果 b - a == 1,f(b) = f(a) + f(a - 1).当 a == b时,f(a) == f(a - 2) + f(a + 1) (自己根据斐波那契数列的性质写一下就出来了)。首先对输入的斐波那契数下标进行排序,看是否有可以合并的,如果有则合并,并再进行排序继续查找,如果找不到,则退出自定义函数,即找到了解,输出即可。说的有点乱,看代码吧
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #define N 500 #define inf 100000000 #define _clr(a,val) (memset(a,val,sizeof(a))) using namespace std; int a[N]; int slove(int num) { int i,j; int flag = 1; while(flag) { flag = 0; for(i = 0; i < num - 1; i++) { if(a[i] == inf) continue; for(j = i + 1; j < num; j++) { if(a[j] == inf) break; if(abs(a[j] - a[i]) > 1) continue; if(!flag) flag = 1; if(a[j] - a[i] == 1) { a[num ++] = a[j] + 1; a[i] = a[j] = inf; } else if(a[i] - a[j] == 1) { a[num ++] = a[i] + 1; a[i] = a[j] = inf; } else if(a[i] == a[j]) { a[num++] = a[i] - 2; a[num++] = a[i] + 1; a[i] = a[j] = inf; } } } sort(a, a + num); } return num; } int main() { int i,j; int t,tem; int cs = 0; scanf("%d",&t); while(t--) { _clr(a,0); int num = 0; int n; for(i = 0; i < 2; i++) { scanf("%d",&n); for(j = 0; j < n; j++) { scanf("%d",&tem); a[num++] = tem; } } sort(a, a + num); int ans = slove(num); printf("Case %d:\n",++cs); num = 0; for(i = 0; i < ans; i++) { if(a[i] == inf) break; if(a[i] > 0) num ++; } cout<<num; for(i = 0; i < ans; i++) { if(a[i] == inf) break; if(a[i] > 0) printf(" %d",a[i]); } cout<<endl; } return 0; }
还有一道题目,看了题意,不知道怎么做,去看解题报告才知道是dp,索性就不做了。