POJ 刷水

这个专题将近过了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即为所求。

ContractedBlock.gif ExpandedBlockStart.gif 代码

   
#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开始累加,由每年的半圆面积求出被侵蚀的半径,直到给定的点被侵蚀结束循环。

ContractedBlock.gif ExpandedBlockStart.gif 代码

   
#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

ContractedBlock.gif ExpandedBlockStart.gif 代码

   
#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 ;
}

 

优化后:

ContractedBlock.gif ExpandedBlockStart.gif 代码

   
#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

按题意对每个串的无序程度升序排序,无序程度相等的按输入次序升序排序。

ContractedBlock.gif ExpandedBlockStart.gif 代码

   
#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

ContractedBlock.gif ExpandedBlockStart.gif 代码

   
#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(
" %03d-%04d %d\n " ,i / 10000 ,i % 10000 ,mark[i]);
flag
= 1 ;
}
}
if (flag == 0 )
puts(
" No duplicates. " );
return 0 ;
}

 

看了清华大学的《程序设计导引及在线实践》,有这道例题,438MS A掉了

ContractedBlock.gif ExpandedBlockStart.gif 代码

   
#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

ContractedBlock.gif ExpandedBlockStart.gif 代码

   
#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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值