2020-1-18学习总结

今天是放假在家打卡学习的第一天。
早上8:30签到打卡。
8:50——12:00学习算法(大数相加,快速幂,部分背包贪心策略,博弈基础之巴什博弈)
14:00——18:00刷题。
晚上归纳总结。

大数相加的思路是以模拟算术的加法进位过程,在这里我们运用了数组来依次存放每一位字符,首先将字符每一位翻转,因为我们是从低位算起,所以需要将低位放在数组头部,在计算过程中也需要用一个临时变量来控制每一位的进位,再循环结束过后还需要对进位的变量判断,如果进位不是1的话还要在后面进位。


  len1=strlen(str1);
    len2=strlen(str2);
    for(i=0; i<len1; i++)
        ans1[i]=str1[len1-i-1]-'0';//对字符串进行翻转
    for(i=0; i<len2; i++)
        ans2[i]=str2[len2-i-1]-'0';
 for(i=0; i<len1||i<len2; i++)
    {
     
        sum[i]=(ans1[i]+ans2[i]+t)%10;//每位剩下的数
        t=(ans1[i]+ans2[i]+t)/10;//取进位
    }
    if(t)//判断是否还有进位
        sum[i++]=t;//有进位的话还需进位
        sum[i]='\0';

快速幂是应用在我们平时求取高次方幂的精简版
一般的是对幂进行循环遍历,这样时间复杂度相对而言会高一点为0(N)。
而快速幂的话是以二进制的位权来简化时间复杂度。(将底数放大,将指数缩小)

void main()
{
        int a,b;
scanf("%d%d",&a,&b);
    int ans=1;
    while(b)
    {
     
        if(b&1)//按位运算相当于b%2!=0
            {
     ans*=a;}
           a*=a;
           b>>=1;//位运算右移相当于除以2
    }
    printf("%d",ans);
}

部分背包策略我就结合今天刷题组的一道题来理解,主要是运用贪心策略。看题:
问题 H: Home Work
描述
临近开学了,大家都忙着收拾行李准备返校,但I_Love_C却不为此担心! 因为他的心思全在暑假作业上:目前为止还未开动(-_-!!还以为他有多冷静呢)。
暑假作业是很多张试卷,我们这些从试卷里爬出来的人都知道,卷子上的题目有选择题、填空题、简答题、证明题等。 而做选择题的好处就在于工作量很少,但又因为选择题题目都普遍很长。 如果有5张试卷,其中4张是选择题,最后一张是填空题,很明显做最后一张所花的时间要比前4张长很多。 但如果你只做了选择题,虽然工作量很少,但表面上看起来也已经做了4/5的作业了。 I_Love_C决定就用这样的方法来蒙混过关。
他统计出了做完每一张试卷所需的时间以及它做完后能得到的价值(按上面的原理,选择题越多价值当然就越高咯)。 现在就请你帮他安排一下,用他仅剩的一点时间来做最有价值的作业。

格式
输入格式
测试数据包括多组。 每组测试数据以两个整数M,N(1≤M≤20, 1≤N≤10000)开头,分别表示试卷的数目和I_Love_C剩下的时间。 接下来有M行,每行包括两个整数T,V(1≤T≤N,0

输出格式
对应每组测试数据输出I_Love_C能获得的最大价值。
保留小数点2位

样例
样例输入 Copy
4 20
4 10
5 22
10 3
1 2
0 0
样例输出 Copy
37.00
提示
float的精度可能不够。 你应该使用double类型。
对平均价值进行降序排序,先取价值高的。代码如下

#include 
#include 
struct node
{
     
    double a[3];

};
int main()
{
     
    int i,j,n,k;
    double s,m;
    struct node arr[1000],t;
    while(~scanf("%d%lf",&n,&s))
    {
     
        if(n==0&&s==0)
            break;
        memset(arr,0,sizeof(arr));//对内存进行重置
        m=0;
        for(i=0; i<n; i++)
        {
     
            scanf("%lf%lf",&arr[i].a[0],&arr[i].a[1]);
            if(arr[i].a[0]==0)//题目说过写题可能为0,但因为除数不能为0
            所以我进行了单独处理
                arr[i].a[2]=arr[i].a[1];
            else
                arr[i].a[2]=arr[i].a[1]/arr[i].a[0];
        }
        for(i=0; i<n-1; i++)//冒泡降序排序,关键字为平均价值
            for(j=0; j<n-1-i; j++)
                if(arr[j].a[2]<arr[j+1].a[2])
                {
     
                    t=arr[j],arr[j]=arr[j+1],arr[j+1]=t;
                }
        i=0;
        while(s)//对价值进行累加,因为是可以进行部分取的
        {
     
            if(s>=arr[i].a[0])
            {
     
                s-=arr[i].a[0];
                m+=arr[i].a[1];
            }
            else
            {
     
                m+=arr[i].a[2]*s;
                s=0;
                break;

            }
            i++;
        }

        printf("%.2lf\n",m);//保留两位小数

    }

}

在刷题题组中运用了博弈基础——巴什博弈
看题
问题 E: 刷题的兄弟俩
描述
众所周知,lbg和gbl是一对兄弟,他们时常位居刷题榜前列,为了赢得学妹的芳心
他们决定进行一场刷题比赛,他们找来了1000000000000000道题,比赛的规则是
1、一道题只能归一个人所有(这题被gbl过了,lbg就接着往后刷);
2、从第一题开始往后刷;
3、谁先刷完最后一题谁就赢了;
4、只有一台机子,每次只能有一个人上机;
5、一次上机刷超过 m (1<=m<=100) 道题会被系统判定为舞弊;
因为lbg和gbl都很聪明,所以每次上机都不会舞弊,而且所有的题他们都会做。
这时比赛已经进行到了晚上就要断网了,还剩 n (0 假设lbg先上机,请问谁能获得小学妹的芳心?

格式
输入格式
输入数据首先包含一个正整数T,表示包含T组测试用例,然后是T行数据,每行包含两个正整数n,m,n和m的含义参见上面提到的规则。

输出格式
对于每组测试数据,如果lbg能获得小学妹的芳心,请输出字符串"lbg", 如果gbl能获得小学妹的芳心,请输出字符串"gbl",每个实例的输出占一行。

样例
样例输入 Copy
2
8 10
11 10
样例输出 Copy
lbg
gbl
这道题算是巴什博弈的模板题把,
因为每次做题的数不超过m道,也就是说每个人每次做题数目都在1至m,所以如果题目数2*m>n>=m+1,也就说明先手必输,因为先手只能拿1~m,后手就可以拿剩下的n-(m),必定是在1—m内的,所以后手必赢。同样如果n是m+1的倍数拿必定可以变成m+1.所以我们只需判断如果是m+1的倍数那必定是后手赢。代码如下:

#include 
int main()
{
     
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {
     
        scanf("%d%d",&n,&m);
        if(n%(m+1)==0)
            printf("gbl\n");
        else
            printf("lbg\n");
    }

}

愿每天都能过的充实,加油大气层!!!!!

你可能感兴趣的:(萌新)