这个专题将近过了10天了吧,这个.doc文件一直存到电脑里,我就把它发出来吧。
1004, 1003, 1005, 1006, 1007, 1002, 1001, 1008, 1163, 1088,2027, 1012, 1046, 1050, 1207, 2000, 1218, 1664, 1011, 1013
北大OJ:http://124.205.79.250/JudgeOnline
PKU1004
12个浮点数求平均值。
PKU1003
根据题意求和1/2 + 1/3 + 1/4 + ... + 1/(i+ 1)
直到sum >=n,结束循环,i-2即为所求。
代码 #include < stdio.h > int main(){ int i; double n,t,sum; while (scanf( " %lf " , & n)) { if (n == 0.00 ) break ; t = 0 ; i = 1 ; sum = 0 ; while (sum < n) { sum += t; i ++ ; t = 1.0 / i; } printf( " %d card(s)\n " ,i - 2 ); } return 0 ;}PKU1005
题目大意:陆地每年被侵蚀50平方英里,给定房子的坐标,求其第几年被侵蚀。(侵蚀从坐标原点开始)。
实现方法:years从1开始累加,由每年的半圆面积求出被侵蚀的半径,直到给定的点被侵蚀结束循环。
代码 #include < stdio.h > #include < math.h > #define PI acos(-1.0) int main(){ int n,i,years; double x,y,dissqu; scanf( " %d " , & n); for (i = 1 ;i <= n;i ++ ){ scanf( " %lf%lf " , & x, & y); dissqu = x * x + y * y; for (years = 1 ; 100 * years < PI * dissqu;years ++ ); printf( " Property %d: This property will begin eroding in year %d.\n " ,i,years); } puts( " END OF OUTPUT. " ); return 0 ;}
PKU1006
生物节律,给出该年内每个属性(physical, emotional or mental)出现峰值的天数,然后计算出各个属性都达到峰值的天数(从给定的天数开始算起)。如果按照题意一步步循环,跑了766MS,优化以后跑63MS
几组数据,很牛啊:
0 4 5 0 368
2 2 2 2 21252
123 128 133 1 99
123 128 133 100 21252
0 1 2 1 16996
1 0 2 1 8119
1 2 0 1 13133
1 2 3 0 16998
117 58 2 27 21227
代码 #include < stdio.h > int main(){ int p,e,i,d,cas = 1 ,k; while (scanf( " %d%d%d%d " , & p, & e, & i, & d) && p + e + i + d !=- 4 ) { for (k = d + 1 ;k <= 21252 + d;k ++ ) { if ((k - p) % 23 != 0 ) continue ; else { if ((k - e) % 28 != 0 ) continue ; else { if ((k - i) % 33 != 0 ) continue ; } } break ; } printf( " Case %d: the next triple peak occurs in %d days.\n " ,cas,k - d); cas ++ ; } return 0 ;}
优化后:
代码 #include < stdio.h > int main(){ int p,e,i,d,cas = 1 ,k; while (scanf( " %d%d%d%d " , & p, & e, & i, & d),p + e + i + d !=- 4 ) { for (k = i % 33 ; ;k += 33 ) { if ((k - p) % 23 == 0 && (k - e) % 28 == 0 && k > d) break ; } printf( " Case %d: the next triple peak occurs in %d days.\n " ,cas ++ ,k - d); } return 0 ;}
PKU1007
按题意对每个串的无序程度升序排序,无序程度相等的按输入次序升序排序。
代码 #include < stdio.h > #include < stdlib.h > struct DNA{ int num; char s[ 52 ]; int unsorted;}dna[ 102 ]; int n; int cmp( const void * a, const void * b){ struct DNA * c = ( struct DNA * )a; struct DNA * d = ( struct DNA * )b; if (c -> unsorted != d -> unsorted) return c -> unsorted - d -> unsorted; return c -> num - d -> num;} int UNSorted( char s[ 52 ]){ int i,j,ans = 0 ; for (i = 0 ;i < n - 1 ;i ++ ) for (j = i + 1 ;j < n;j ++ ) if (s[i] > s[j]) ans ++ ; return ans;} int main(){ int m,i; while (scanf( " %d%d " , & n, & m) != EOF){ getchar(); for (i = 0 ;i < m;i ++ ){ gets(dna[i].s); dna[i].num = i; dna[i].unsorted = UNSorted(dna[i].s); } qsort(dna,m, sizeof (dna[ 0 ]),cmp); for (i = 0 ;i < m;i ++ ) puts(dna[i].s); } return 0 ;}
PKU1002
找出重复的电话号码,附带两组数据。我的方法是先开一个10000000大的数组,对每个翻译成数字的电话号码进行标记(加1),输出出现次数大于1的号码及次数。没有重复输出"No duplicates."。这个方法跑了688MS,有待优化啊。
4
0000000
0010001
0000000
0010001
2
0000000
0010001
代码 #include < stdio.h > #include < string .h > #include < ctype.h > #include < math.h > int mark[ 10000000 ]; int main(){ int n,t,i,num,flag; char s[ 50 ]; int match[ 26 ] = { 2 , 2 , 2 , 3 , 3 , 3 , 4 , 4 , 4 , 5 , 5 , 5 , 6 , 6 , 6 , 7 , 0 , 7 , 7 , 8 , 8 , 8 , 9 , 9 , 9 , 0 }; memset(mark, 0 , sizeof (mark)); scanf( " %d " , & n); getchar(); while (n -- ) { gets(s); t = 6 ; num = 0 ; for (i = 0 ;s[i];i ++ ) { if (isupper(s[i])) num += match[s[i] - ' A ' ] * ( int )pow( 10.0 ,t -- ); if (isdigit(s[i])) num += (s[i] - ' 0 ' ) * ( int )pow( 10.0 ,t -- ); } mark[num] ++ ; } flag = 0 ; for (i = 0 ;i <= 9999999 ;i ++ ) { if (mark[i] > 1 ) { printf( " d-d %d\n " ,i / 10000 ,i % 10000 ,mark[i]); flag = 1 ; } } if (flag == 0 ) puts( " No duplicates. " ); return 0 ;}
看了清华大学的《程序设计导引及在线实践》,有这道例题,438MS A掉了
代码 #include < stdio.h > #include < stdlib.h > #include < string .h > char map[] = " 22233344455566677778889999 " ; char str[ 80 ],telNumbers[ 100000 ][ 9 ]; int cmp( const void * a, const void * b){ return strcmp(( char * )a,( char * )b);} void standardizeTel( int n){ int j, k; j = k = - 1 ; while (k < 8 ) { j ++ ; if (str[j] == ' - ' ) continue ; k ++ ; if (k == 3 ) { telNumbers[n][k] = ' - ' ; k ++ ; } if (str[j] >= ' A ' && str[j] <= ' Z ' ){ telNumbers[n][k] = map[str[j] - ' A ' ]; continue ; } telNumbers[n][k] = str[j]; } telNumbers[n][k] = ' \0 ' ; return ;} int main(){ int n, i, j; bool noduplicate; scanf( " %d " , & n); for (i = 0 ;i < n;i ++ ){ scanf( " %s " ,str); standardizeTel(i); } qsort(telNumbers,n, sizeof (telNumbers[ 0 ]),cmp); noduplicate = true ; i = 0 ; while (i < n) { j = i; i ++ ; while (i < n && strcmp(telNumbers[i],telNumbers[j]) == 0 ) i ++ ; if (i - j > 1 ){ printf( " %s %d\n " ,telNumbers[j],i - j); noduplicate = false ; } } if (noduplicate) puts( " No duplicates. " ); return 0 ;}PKU1001
这一题大整数相乘,还带小数点。要考虑的情况很多,处理起来不是很容易啊。
0.0100 2
4.00 2
10.00 2
10 2
代码 #include < stdio.h > #include < string .h > #define N 1500 void rev( char a[N]) // 字符串倒置函数,POJ不支持strrev库函数 { char b[N]; int i,len = strlen(a); for (i = 0 ;i < len;i ++ ) b[i] = a[len - 1 - i]; b[i] = ' \0 ' ; strcpy(a,b);} void mul( char a[N], char b[N]) // a和b相乘,结果存入b中 { char c[N]; int temp[N] = { 0 }; int i,j,k,carry,len1,len2; rev(a); rev(b); len1 = strlen(a); len2 = strlen(b); for (i = 0 ;i < len1;i ++ ) { k = i; for (j = 0 ;j < len2;j ++ ) temp[k ++ ] += (a[i] - 48 ) * (b[j] - 48 ); } carry = 0 ; for (i = 0 ;i < k;i ++ ) { temp[i] += carry; carry = temp[i] / 10 ; c[i] = temp[i] % 10 + 48 ; } if (carry > 0 ) c[i ++ ] = carry + 48 ; c[i] = ' \0 ' ; rev(c); strcpy(b,c); rev(a);} int main(){ char a[N],b[N],c[N]; int i,j,len,n,m,num; while (scanf( " %s%d " ,a, & n) == 2 ) { num = 0 ; len = strlen(a); for (i = 0 ;i < len;i ++ ) // 找到并记下小数点的位置,并把它去点 { if (a[i] == ' . ' ) { len -- ; num = len - i; for (;i < len;i ++ ) { a[i] = a[i + 1 ]; } a[i] = ' \0 ' ; break ; } } j = 0 ; for (i = 0 ;i < len - 1 ;i ++ ) // 消除串a的前导'0' { if (a[i] != ' 0 ' ) { for (;i < len;i ++ ) { a[j ++ ] = a[i]; } a[j] = ' \0 ' ; break ; } } m = n; strcpy(b, " 1 " ); // 初始化b while (n) // 这里用到快速幂取模,用n的二进制形式求幂结果 { if (n % 2 ) mul(a,b); strcpy(c,a); mul(c,a); n /= 2 ; } len = strlen(b); // 求得结果存入b num *= m; // num为b中小数点位置,从后向前查 if (num != 0 ) { if (num <= len) { for (i = len;i > len - num;i -- ) b[i] = b[i - 1 ]; b[i] = ' . ' ; b[ ++ len] = ' \0 ' ; } if (num > len) // 如果b的位数不够,这前面补'0',用以加小数点 { for (i = num,j = len - 1 ;i > num - len;i -- ,j -- ) b[i] = b[j]; b[ ++ num] = ' \0 ' ; for (i = 1 ;i < num - len;i ++ ) b[i] = ' 0 ' ; b[ 0 ] = ' . ' ; len = num; } for (i = len - 1 ;i > 0 ;i -- ) // 消掉小数末尾的'0' { if (b[i] != ' 0 ' ) break ; else { len -- ; b[i] = ' \0 ' ; } } } if (b[len - 1 ] == ' . ' ) // 如果小数点后面全是'0',小数点也要去掉 { b[len - 1 ] = ' \0 ' ; len -- ; } puts(b); memset(a, 0 , sizeof (a)); memset(b, 0 , sizeof (b)); memset(c, 0 , sizeof (c)); } return 0 ;}
转载于:https://www.cnblogs.com/DreamUp/archive/2010/07/22/1783272.html
相关资源:POJ、HDU、ZOJ、SOJ水题过滤器