poj1000-1009小结

蒟蒻一枚,开始从poj做起。废了n久时间且参考有些参考大神博客才写完poj10题。但总算是写完了,小结一下。

poj1000 A+B

经典题目,不解释,过。

poj1001 Exponentiation

  1. 大意

    1. 求R的n次方。
    2. 忽略小数点前的前导0,小数点的后导0输出。如0.50输出为:

      .5
  2. 算法
    1. 高精度乘以int
  3. 代码
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std; char s[10];
int a,n,p_cnt; struct bign{
int a[140];
int p_cnt;
void set(int a0,int p_cnt0)
{
int i;
p_cnt=p_cnt0;
for(i=0;a0;i++) {
a[i]=a0%10;
a0/=10;
}
for(;i<140;i++) a[i]=0;
}
struct bign operator *(int b)
{
int i,t;
bign c;
for(t=i=0;i<140;i++) {
t=a[i]*b+t;
c.a[i]=t%10;
t/=10;
}
return c;
}
void p()
{
int i,j;
for(i=140-1;i>=p_cnt;i--)
if(a[i]) break;
for(j=0;j<p_cnt;j++)
if(a[j]) break;
if(i<p_cnt&&j>=p_cnt)
puts("0");
else {
for(;i>=p_cnt;i--)
printf("%d",a[i]);
if(j<p_cnt) putchar('.');
for(i=p_cnt-1;i>=j;i--)
printf("%d",a[i]);
printf("\n");
}
}
}r,ans;
int init()
{
if(cin>>s>>n) {
char *p=strchr(s,'.');
p_cnt=s+strlen(s)-p-1;
strcpy(p,p+1);
sscanf(s,"%d",&a);
return 1;
} else {
return 0;
}
}
void cal()
{
int nn=n;
r.set(a,p_cnt);
ans.set(1,0);
while(n--)
ans=ans*a;
ans.p_cnt=p_cnt*nn;
}
int main()
{
while(init()){
r.set(a,p_cnt);
cal();
ans.p();
}
}

poj1002

  1. 大意

    1. 公司为了便于记忆电话号码,采取了不同的分隔方法和把字母映射为某一个数字
  2. 算法
    1. 直接把输入搞成一个7位数,暴力开数组记录出现次数,最后按标准格式输出。
  3. 代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h> int n;
int num_cnt[10000001],num,ans_cnt;
char s[100],c,p[8];
void get_std(char p[],char s[])
{
int i,j;
for(j=i=0;s[i];i++) {
if(s[i]>='0'&&s[i]<='9') p[j++]=s[i];
switch(s[i]) {
case 'Q':
case 'Z':
case '-':break;
case 'A':
case 'B':
case 'C':p[j++]='2';break;
case 'D':
case 'E':
case 'F':p[j++]='3';break;
case 'G':
case 'H':
case 'I':p[j++]='4';break;
case 'J':
case 'K':
case 'L':p[j++]='5';break;
case 'M':
case 'N':
case 'O':p[j++]='6';break;
case 'P':
case 'R':
case 'S':p[j++]='7';break;
case 'T':
case 'U':
case 'V':p[j++]='8';break;
case 'W':
case 'X':
case 'Y':p[j++]='9';break;
}
}
}
int main()
{
int i;
scanf("%d\n",&n);
memset(num_cnt,0,sizeof(num_cnt));
while(n--){
gets(s);
get_std(p,s);
sscanf(p,"%d",&num);
num_cnt[num]++;
}
ans_cnt=0;
for(i=0;i<=10000000;i++)
if(num_cnt[i]>1) {
ans_cnt++;
printf("%03d-%04d %d\n",i/10000,i%10000,num_cnt[i]);
}
if(ans_cnt==0) puts("No duplicates.");
}

poj1003

题目已经给了公式,直接计算出,然后计算即可。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
double a[1000];
int ans[521];
int main()
{
int i,j;
int x,y;
a[1]=0.50;
for(i=2;a[i-1]<5.20;i++)
a[i]=a[i-1]+1.0/(i+1);
//printf("%d\n",i);
for(i=1,j=1;j<521;j++) {
while(a[i]<j/100.0) i++;
ans[j]=i;
}
do{
scanf("%d.%d",&x,&y);
if(x==0&&y==0)
break;
printf("%d card(s)\n",ans[x*100+y]);
}while(1);
return 0;
}

poj1004 Financial Management

其实就是求12个数的平均数,保留两位小数。

但是我wa了很多次。根源在于浮点数的精度原因。

wa 1

#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
double a[12],sum,ans;
int i;
for(i=0;i<12;i++) cin>>a[i];
for(sum=i=0;i<12;i++) sum+=a[i];
ans=sum/12;
printf("$%.02lf\n",ans);
return 0;
}

wa 2

#include<cstdio>
using namespace std;
int main()
{
int i;
double tmp,sum;
sum=0.0;
for (i=0;i<12;i++)
{
scanf("%lf", &tmp);
sum+=tmp;
}
printf("$%.2lf\n",sum/12);
return 0;
}

然后找了一个大神的程序发现大神输出使用cout的格式化输出的,而我并不会cout.大神是这样子的

    cout<<fixed<<setprecision(2)<<'$'<<sum/12.0<<endl;

用大神的代码提交了一下,A了。然后我就觉得,一定要用printf写出来。然后各种百度。期间wa了无数次。又说printf格式化输出就是四舍五入的,又说是截断的,又说根据程序运行结果来看不是截断是四舍五入的。最后看到有人说设计的是想四舍五入的,但是因为实型的存储机制blablabla的导致有些并不是四舍五入的。然后又有各种版本的四舍五入的正确输出方法的。有这样说的(注:我是用sum存储的平均数,逃)

version1

sum=(int)(sum*100+0.5)/100.0;
printf("$%.2lf\n",sum);

version2

sum+=0.005;
printf("$%.2lf\n",sum);

最后我是这么干的A掉了

ans=(int)round(sum*100.0);
printf("$%d.%02d",ans/100,ans%100);

经验

实型精度问题要注意,四舍五入不简单。

poj1005

大意

一个半圆每年扩充面积值50.给出点的坐标,问第几年会被覆盖。保证点不会在某一年的圆的边界上。

代码

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
using namespace std;
const double pi=atan(1)*4;
const double k=2*50/pi;
int l,r,m;
int main(void)
{
int n;
double x,y;
cin>>n;
for(int i=1;i<=n;i++) {
cin>>x>>y;
x=x*x+y*y;
/*l=0; r=20000000;
while(r-l>1) {
m=(l+r)/2;
if (k*m>x)
r=m;
else
l=m;
}*/
r=1+(int)floor(x/k);
cout<<"Property "<<i<<": This property will begin eroding in year "<<r<<"."<<endl;
}
cout<<"END OF OUTPUT."<<endl;
return 0;
}

poj1006

大意

人有三种巅峰,周期性出现,周期数题面说了,给出这三种巅峰的各自出现的一天。问第t天后至少过多少天会出现三种巅峰在同一天出现。

数论题

中国剩余定理

代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
int e_gcd(int a,int b,int &x,int &y)
{
if(b==0) {
x=1; y=0;
return a;
}
int ans=e_gcd(b,a%b,x,y);
int tmp=x;
x=y; y=tmp-a/b*y;
} int crt(int r[],int m[],int n)
{
int M=1,ans=0;
for(int i=0;i<n;i++) M*=m[i];
for(int i=0;i<n;i++) {
int x,y,mi=M/m[i];
e_gcd(mi,m[i],x,y);
ans=(ans+mi*x*r[i])%M;
}
if(ans<0) ans+=M;
return ans;
} int main()
{
int p,e,i,d,t=1,k=21252;
int a[3],m[3];
do{
cin>>p>>e>>i>>d;
if(p==-1&&e==-1&&i==-1&&d==-1) break;
a[0]=p; a[1]=e; a[2]=i;
m[0]=23; m[1]=28; m[2]=33;
int ans=crt(a,m,3);
ans-=d;
if(ans<=0) ans+=21252;
cout<<"Case "<<t++<<": the next triple peak occurs in "<<ans<<" days."<<endl;
}while(1);
return 0;
}

poj1007

大意

给出若干等长的DNA序列,按照序列中的逆序对个数从少到多排序后输出。

算法

归并排序并求逆序对个数。最后按照逆序对个数排序。

源码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define array_len 1000
int merge_tmp[array_len];
void merge_cnt(int a[],int l,int r,int &cnt,int tmp[])
{
int m=(l+r)/2,i=l,j=m+1,k=l;
while(i<=m&&j<=r) {
if(a[i]>a[j]) {
tmp[k++]=a[j];
cnt+=m+1-i;
j++;
} else {
tmp[k++]=a[i];
i++;
}
}
while(i<=m) tmp[k++]=a[i++];
while(j<=r) tmp[k++]=a[j++];
while (l<=r) {
a[l]=tmp[l];
l++;
}
}
void merge_srt_cnt(int a[],int l,int r,int &cnt,int tmp[])
{
if(l<r) {
int m=(l+r)/2;
merge_srt_cnt(a,l,m,cnt,tmp);
merge_srt_cnt(a,m+1,r,cnt,tmp);
merge_cnt(a,l,r,cnt,tmp);
}
} void merge_cnt(char a[],int l,int r,int &cnt,char tmp[])
{
int m=(l+r)/2,i=l,j=m+1,k=l;
while(i<=m&&j<=r) {
if(a[i]>a[j]) {
tmp[k++]=a[j];
cnt+=m+1-i;
j++;
} else {
tmp[k++]=a[i];
i++;
}
}
while(i<=m) tmp[k++]=a[i++];
while(j<=r) tmp[k++]=a[j++];
while (l<=r) {
a[l]=tmp[l];
l++;
}
}
void merge_srt_cnt(char a[],int l,int r,int &cnt,char tmp[])
{
if(l<r) {
int m=(l+r)/2;
merge_srt_cnt(a,l,m,cnt,tmp);
merge_srt_cnt(a,m+1,r,cnt,tmp);
merge_cnt(a,l,r,cnt,tmp);
}
}
struct dna{
char s[52];
int invrsn;
bool operator <(dna b)
{
if(invrsn!=b.invrsn)
return invrsn<b.invrsn;
else
return strcmp(s,b.s)<0;
}
}a[100];
char s[52];
char tmps[52]; int main()
{
int n,m,i;
cin>>n>>m;
for(i=0;i<m;i++) {
cin>>s;
strcpy(a[i].s,s);
a[i].invrsn=0;
merge_srt_cnt(s,0,n-1,a[i].invrsn,tmps);
}
sort(a,a+m);
for(i=0;i<m;i++) cout<<a[i].s<<endl;
return 0;
}

poj1008

模拟水题,不解释

#include<stdio.h>
#include<string.h>
char p[20][15]={"pop","no","zip","zotz","tzec","xul","yoxkin","mol","chen",
"yax","zac","ceh","mac","kankin","muan","pax","koyab","cumhu",
"uayet"};
char q[20][15]={"imix","ik","akbal","kan","chicchan","cimi","manik","lamat",
"muluk","ok","chuen","eb","ben","ix","mem","cib","caban",
"eznab","canac","ahau"}; int get_mnth_ind(char *m)
{
int i;
for(i=0;i<19;i++)
if(strcmp(m,p[i])==0)
return i;
return -1;
}
int main()
{
int n,mnth_day,mnth_ind,year,day;
char s[15];
scanf("%d",&n);
printf("%d\n",n);
while(n--){
scanf("%d. %s %d",&mnth_day,s,&year);
mnth_ind=get_mnth_ind(s);
day=year*365+mnth_ind*20+mnth_day;
//printf("day=%d\n",day);
year=day/260; day%=260;
mnth_day=day%13+1; mnth_ind=day%20;
printf("%d %s %d\n",mnth_day,q[mnth_ind],year);
}
return 0;
}

poj1009

大意

图片有很多像素,不直接存储每个图片的像素值,而是以RLE,即

像素值V 长度L

表示连续L个像素的值是V。用这种RLE存储方式以节约空间。现在需要计算每个像素与周围8个格子的最大像素差(取绝对值)取代原来的像素值以生成一副新图。新图的输出格式与输入格式相同。

图的像素很多,10^9级别的。

RLE对数输入数据保证最多1000对。

算法

自己画了几张图,发现只有变化的那个起点及起点周围8个点才回因为有这个变化的点出现导致最大像素差可能改变,而其他的新像素值应该和前面一个(最左边的前一个点是上一行最后一个点)像素点相同。然后又画了图形式的证明了一下,发现的确是这样。然后按照这种方法写。

故事

一开始怕有大量test cases而超时,还用了二分查找确定像素值。

然而wa了。于是先改成直接扫描查找确保查找确定像素值没错,然而还是wa.思考了许久还是不解,然后百度,然后发现我的思路和大神思路差不多。然后阅读代码,觉得和大神的是等价的。然后整个人就不好了。

自己写了个数据生成器,用大神和自己的对拍。发现了一个很大的错误数据,调试了n久,表示数据太大,调试好累,调试了一个小时无果。

最后躺床上,早上突然醒来看到那张自己画的形式的证明的图,脑袋中过了一下证明的过程,发现自己的证明有一个bug,图片的终结最后一行的后一行是没有的,这个就和前面的不一样,要特殊考虑或者把这个特殊处理使其符合前面形式证明的条件一样。然后我就把原来的输入的RLE对增加了一队

-1 width

或者直接增加一个起始变化点

total val

其中total是图的总像素点,val随便什么无所谓

源码

//WA
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
struct node{
int pos;
int val;
void set(int p,int v){pos=p;val=v;}
bool operator <(node b){return pos<b.pos;}
}a[2005],b[16500];
int width,total,height,pos,acnt,bcnt;
int get_val(int pos)
{
int i;
for(i=0;i<acnt;i++)
if(pos>=a[i].pos&&pos<a[i+1].pos)
return a[i].val;
}
void cal(int pos)
{
int r,c,j,k,tpos,val,tval=0;
val=get_val(pos);
r=pos/width; c=pos%width;
for(j=-1;j<=1;j++) {
if((c==0&&j==-1)||(c==width-1&&j==1)) continue;
for(k=-1;k<=1;k++) {
if((r==0&&k==-1)||(r==height-1&&k==1)) continue;
tpos=(r+k)*width+c+j;
tval=max(tval,abs(val-get_val(tpos)));
}
}
b[bcnt++].set(pos,tval);
}
int main()
{
int r,c,j,k,i;
int val,l;
while(1) {
scanf("%d",&width);
if(width==0) break;
acnt=bcnt=pos=total=0;
while(1) {
scanf("%d%d",&val,&l);
if(val==0&&l==0) break;
a[acnt++].set(pos,val);
pos+=l;
}
a[acnt].set(pos,val);//AC版本修改这里,修改为acnt++.但是一开始这样写并不是疏忽落了++,而是一开始之时为了增加这个节点来让查找更方便,未考虑到把这个变成一个起始变化点
total=pos; height=total/width;
for(i=0;i<acnt;i++) {
r=a[i].pos/width; c=a[i].pos%width;
for(j=-1;j<=1;j++) {
if((c==0&&j==-1)||(c==width-1&&j==1)) continue;
for(k=-1;k<=1;k++) {
if((r==0&&k==-1)||(r==height-1&&k==1)) continue;
cal((r+k)*width+c+j);
}
}
}
b[bcnt].set(total,-1);
sort(b,b+bcnt);
printf("%d\n",width);
pos=0;
for(i=0;i<bcnt;i=j) {
for(j=i+1;j<bcnt;j++)
if(b[j].val!=b[i].val) break;
printf("%d %d\n",b[i].val,b[j].pos-b[i].pos);
}
printf("0 0\n");
}
printf("0\n");
return 0;
}
//AC
/*上面改了,增加一个起始变化点。同时因为这个点的增加,修改了判断是否点是否合法的判断条件。毕竟原来的判断是基于起始变化点是合法点。
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
struct node{
int pos;
int val;
void set(int p,int v){pos=p;val=v;}
bool operator <(node b){return pos<b.pos;}
}a[2005],b[16500];
int width,total,height,pos,acnt,bcnt;
int get_val(int pos)
{
int i;
for(i=0;i<acnt;i++)
if(pos>=a[i].pos&&pos<a[i+1].pos)
return a[i].val;
}
void cal(int pos)
{
int r,c,j,k,tpos,val,tval=0;
val=get_val(pos);
r=pos/width; c=pos%width;
for(j=-1;j<=1;j++) {
if((c+j<0)||(c+j>=width)) continue;
for(k=-1;k<=1;k++) {
if((r+k<0)||(r+k>=height)) continue;
tpos=(r+k)*width+c+j;
tval=max(tval,abs(val-get_val(tpos)));
}
}
b[bcnt++].set(pos,tval);
}
int main()
{
int r,c,j,k,i;
int val,l;
while(1) {
scanf("%d",&width);
if(width==0) break;
acnt=bcnt=pos=total=0;
while(1) {
scanf("%d%d",&val,&l);
if(val==0&&l==0) break;
a[acnt++].set(pos,val);
pos+=l;
}
a[acnt++].set(pos,val);//这里修改了
total=pos; height=total/width;
for(i=0;i<acnt;i++) {
r=a[i].pos/width; c=a[i].pos%width;
for(j=-1;j<=1;j++) {
if((c+j<0)||(c+j>=width)) continue;
for(k=-1;k<=1;k++) {
if((r+k<0)||(r+k>=height)) continue;
cal((r+k)*width+c+j);
}
}
}
b[bcnt].set(total,-1);
sort(b,b+bcnt);
printf("%d\n",width);
pos=0;
for(i=0;i<bcnt;i=j) {
for(j=i+1;j<bcnt;j++)
if(b[j].val!=b[i].val) break;
printf("%d %d\n",b[i].val,b[j].pos-b[i].pos);
}
printf("0 0\n");
}
printf("0\n");
return 0;
}

经验

边界是特殊的,最好多考虑,看是否和普通的一样,能否特判断或者能否转化程普通的。

poj1000-1009小结的更多相关文章

  1. Android开发之漫漫长途 XI——从I到X的小结

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  2. pandas用法小结

    前言 个人感觉网上对pandas的总结感觉不够详尽细致,在这里我对pandas做个相对细致的小结吧,在数据分析与人工智能方面会有所涉及到的东西在这里都说说吧,也是对自己学习的一种小结! pandas用 ...

  3. MVC图片上传详解 IIS (安装SSL证书后) 实现 HTTP 自动跳转到 HTTPS C#中Enum用法小结 表达式目录树 “村长”教你测试用例 引用provinces.js的三级联动

    MVC图片上传详解   MVC图片上传--控制器方法 新建一个控制器命名为File,定义一个Img方法 [HttpPost]public ActionResult Img(HttpPostedFile ...

  4. 从零开始编写自己的C#框架(26)——小结

    一直想写个总结,不过实在太忙了,所以一直拖啊拖啊,拖到现在,不过也好,有了这段时间的沉淀,发现自己又有了小小的进步.哈哈...... 原想框架开发的相关开发步骤.文档.代码.功能.部署等都简单的讲过了 ...

  5. Python自然语言处理工具小结

    Python自然语言处理工具小结 作者:白宁超 2016年11月21日21:45:26 目录 [Python NLP]干货!详述Python NLTK下如何使用stanford NLP工具包(1) [ ...

  6. java单向加密算法小结(2)--MD5哈希算法

    上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...

  7. iOS--->微信支付小结

    iOS--->微信支付小结 说起支付,除了支付宝支付之外,微信支付也是我们三方支付中最重要的方式之一,承接上面总结的支付宝,接下来把微信支付也总结了一下 ***那么首先还是由公司去创建并申请使用 ...

  8. iOS 之UITextFiled/UITextView小结

    一:编辑被键盘遮挡的问题 参考自:http://blog.csdn.net/windkisshao/article/details/21398521 1.自定方法 ,用于移动视图 -(void)mov ...

  9. K近邻法(KNN)原理小结

    K近邻法(k-nearst neighbors,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用.比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出 ...

随机推荐

  1. drf序列化高级、自定义只读只写、序列化覆盖字段、二次封装Response、数据库查询优化(断关联)、十大接口、视图家族

    目录 自定义只读 自定义只写 序列化覆盖字段 二次封装Response 数据库关系分析 断外键关联关系 ORM操作外键关系 ORM四种关联关系 基表 系列化类其他配置(了解) 十大接口 BaseSer ...

  2. SignalR—实例

    本例子将讲述使用SignalR实现页面实时显示数据,而不是需要用户刷新页面或使用Ajax轮询才能实现实时显示数据. 1.使用NuGet安装SignalR. 2.创建Hub类,起名为testHub. 3 ...

  3. C# NewtonJson Serialize and deserialize

    using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using Sys ...

  4. Spring有哪些配置方式

    1.XML 配置文件. Bean 所需的依赖项和服务在 XML 格式的配置文件中指定.这些配置文件通常包含许多 bean 定义和特定于应用程序的配置选项.它们通常以 bean 标签开头.例如: < ...

  5. Javascript 基础学习(三)js 的原始类型和声明变量

    java的基本数据类型一共有 byte short int long float double char boolean js中定义变量使用关键字 var js的原始类型(五个) String: 字符 ...

  6. C#中的WinFrom技术实现串口通讯助手(附源码)

    C#中的WinFrom技术实现串口通讯助手(附源码)   实现的功能: 1.实现自动加载可用串口. 2.打开串口,并且使用C#状态栏显示串口的状态. 3.实现了串口的接收数据和发送数据功能. 4.串口 ...

  7. npm常用命令和脚手架使用

    最近前端同学使用最多的莫过于vue,angualr,react等热门前端框架了.那么就避免不掉的使用npm命令,本人就经常因为这三个脚手架的使用而不得不百度相应的npm命令,不胜其烦,,,因此就整理一 ...

  8. gcc 将两个文件合成一个文件(c)

    一个文件是: 一个文件是: 两个文件的作用是输出一段文字,其中一个文件调用了另一个文件 gcc 命令为: -c 生成了object 文件,-o 生成了可执行文件,并且合成.

  9. CF #623 div.2

    序 话说,总有人认为我是黑别人电脑的(雾??其实,我不黑电脑,我黑手机. T1 此题巨水,比较四个面积就就好了.. /* make by ltao */ #include <iostream&g ...

  10. wondiws+centos 双系统

    任务:在windows下安装CentOS 1.下载CentOS镜像文件,准备一个未格式化的空间. 2.使用UltraISO将要安装的系统写入U盘. 3.用U盘启动,将系统装入一个空的分区下(未格式化) ...