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即为所求。

代码
#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(
"%03d-%04d %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;
}

 

posted @ 2010-07-22 20:21  孟起  阅读(448)  评论(0编辑  收藏  举报