ACM集训day1

来源:互联网 发布:ppmate网络电视手机版 编辑:程序博客网 时间:2024/04/30 00:40

7.11

要点:0.枚举法 1.求最大公因数 2.记忆化思想

note:善于计算时间复杂度

0 1 枚举法 分类枚举、暴力 求最大公因数 辗转相除>发散->最小公倍数 记忆化思想 预处理、前缀和思想

思考题0.0:

指出斐波那契数列和辗转相除法的相关性,大致分析一下辗转相除法的时间复杂度

思考题0.1:

用记忆化思想优化以下程序 #include <iostream>using namespace std;int fib(int n){    if (n==0 || n==1) return 1;    int ans=fib(n-2)+fib(n-1);    return ans;}int main(){    int n;     scanf("%d",&n);    printf("%d\n",fib(n));    return 0;}

===========================我是分割线=============================

习题

A题 Least Common Multiple

**
思路:求出相邻两数的最小公倍数,再与第三个数求最小公倍数,如此反复直到结束

#include<stdio.h>#include<vector>#include<algorithm>using namespace std;int gcd(int a,int b);int main(){    int n,m;    scanf("%d",&n);    while(n--)    {        int a[100];        int i;        scanf("%d",&m);        for(i=0;i<m;i++)            scanf("%d",&a[i]);        for(i=1;i<m;i++)        {            a[i]=a[i]/gcd(a[i],a[i-1])*a[i-1];//**最小公倍数=两数乘积/最大公约数**(用到这个公式是难点),储存在a[i]        }        printf("%d\n",a[i-1]);    }    return 0;}int gcd(int a,int b) //辗转相除法求最大公约数{    if(a<b)          //判定可不要,一轮之后始终会a>b        swap(a,b);    while(b!=0)       {        int t;        t=a;        a=b;        b=t%b;    }    if(b==0)        return a;}

===========================我是分割线=============================

B题 进制转换

思路:回想10进制转成2进制,除以2取余除以2取余…倒过来输出,一样的道理

#include<stdio.h>int main(){   int n,r,a[1000];   while(scanf("%d %d",&n,&r)!=EOF)   {       int i,j;       int tag=1;       if(n<0)        //若是负数,先取其相反数,否则余数全是负数       {            n=(-1)*n;          tag=0;       }       for(i=0;n!=0;i++) //把余数存进数组       {           a[i]=n%r;           n/=r;       }        if(tag==0)            printf("-");    //负数前面先输出-       for(j=i-1;j>=0;j--)        //倒序输出       {           if(a[j]>=10)           {               switch(a[j])           {               case 10:printf("A");break;   //超过或等于十,换成16进制那样输出,也可以用'A'+i               case 11:printf("B");break;               case 12:printf("C");break;               case 13:printf("D");break;               case 14:printf("E");break;               case 15:printf("F");break;               default:break;           }           continue;           }           printf("%d",a[j]);       }        printf("\n");   }    return 0;}

===========================我是分割线=============================

C题

这题没什么好说的了…只怪眼瞎把正数看成正整数WA个不停233

#include<stdio.h>int main(){    int i,n;    scanf("%d",&n);    for(i=0;i<n;i++)    {        double a,b,c;        scanf("%lf%lf%lf",&a,&b,&c);        if(a+b>c&&a+c>b&&b+c>a&&a&&b&&c)            printf("YES\n");    //**有时题目(下面E题)会叫输出“Yes”,注意别被坑!**        else            printf("NO\n");    }    return 0;

===========================我是分割线=============================

D题 空心三角形

**
note:反复多次读入一个字符型%c会出错

#include<stdio.h>#include<string.>#include<conio.h>int main(){   int gao;   char hua,str[10];   int test=0;   while(1)   {       scanf("%s",str);  //一开始这里用了%c,结果输出来的图案之前多了很多莫名的空行,输出样例越多,空行越多。**用字符串读入,取它第一个字符可以避免莫名的错误!**       hua=str[0];       if(hua=='@')        return 0;        else            if (test) printf("\n"); //**这个判定很重要**输入@结束后不再换行,其他情况输入后空行再输出结果       test++;       scanf("%d",&gao);       int i,j,k;       for(i=0;i<gao;i++)       {           if(i==gao-1)           {               for(k=0;k<2*gao-1;k++)               printf("%c",hua);                printf("\n");           }           else           {               for(j=0;j<gao-i-1;j++)                    printf(" ");                printf("%c",hua);                if(i==0)                {                    printf("\n");                    continue;                }                for(j=0;j<2*i-1;j++)                    printf(" ");                printf("%c\n",hua);           }       }       //fflush(stdin); //网上的judge没有键盘缓存,没有意义,   }    return 0;}

===========================我是分割线=============================

E题

note:多多留意题目叫你输出什么!YES?!Yes?!yes?!

#include<stdio.h>int main(){    int a,b,i;     while(scanf("%d%d",&a,&b)&&(a||b))    {            int tag=0;            for(i=-10000;i<10000;i++)            if((a-i)*i==b)            {                 printf("Yes\n");                 tag=1;                 break;            }        if(tag==0)            {                printf("No\n");            }    }    return 0;}

F题没A出来…TAT…
===========================我是分割线=============================

G题

思路:函数判断漂亮数->定义数组表示从1到i的漂亮数总数->记忆化思想->指定区间

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<vector>#include<algorithm>using namespace std;int Isbeauty(int x);int main(){    int n,sum[100001]={0};//储存前i个数的和    scanf("%d",&n);    for(int i=1;i<=100000;i++) //**i从1开始**    {        sum[i]=sum[i-1]+Isbeauty(i);  **//记忆化思想,优化时间复杂度,否则每次都要1到十万算很可能超时**    }    while(n--)    {        int l,r;        scanf("%d %d",&l,&r);        printf("%d\n",sum[r]-sum[l-1]); //[l,r]闭区间    }    return 0;}int Isbeauty(int x)  //判定是否漂亮数{    int a[11]={0};    while(x!=0)    {        if(a[x%10])  //之前出现过一次            return 0;  //返回0,不是漂亮数        else            a[x%10]++;          x/=10;          }    return 1;  //没出现过重复,返回1,是漂亮数}

有点忙不过来啊,当天的练习没及时整理…开个好头,祝自己在ACM路上越来越强~

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机运行内存2g不够怎么办 手机无法加载程序秒退怎么办 电脑账户密码忘记了怎么办 玩绝地求生卡顿怎么办 地下城总运行时间错误怎么办 逆战更新太慢怎么办 win7我的电脑没了怎么办 剑灵启动游戏慢怎么办 网页页面结束进程也关不掉怎么办 开机就启动微信怎么办 微信突然无法启动怎么办 微信发送太频繁怎么办 微信在电脑上打不开文件怎么办 微信照片电脑上打不开怎么办 换一部手机微信怎么办 微信支付宝停止运行怎么办 剑三重制版卡顿怎么办 剑三客户端更新不动了怎么办 安装包安装失败怎么办有内存 qq飞车换手机了怎么办 qq飞车求婚失败戒指怎么办 改脸型皮肤会下垂怎么办 情侣关系弄僵了怎么办 用微信交话费没有到账怎么办 微信交错话费了怎么办 微信缴费交错了怎么办 微信支付被投诉怎么办 微信q币充值错误怎么办 微信充值流量充错了怎么办 微信延迟到账怎么办 移动流量充错了怎么办 qq充话费等待发货怎么办 qq充值话费没到账怎么办 电信话费冲错了怎么办 微信手机充错话费充空号怎么办 京东地址写错了怎么办 京东售后不退款怎么办 冲了话费不到账怎么办 币安维护充值怎么办 微信话费未到账怎么办 微信话费交错了怎么办