day_7-acm 周赛总结(1)

A: 区间or值

题目:

gbx从老板那里获得了一个长度为n的非负整数序列,以及老板的一个需求。老板要gbx写一个程序支持查询一个区间的or的结果。当老板给出一个区间[x,y]的时候,gbx就必须立刻告诉老板A[x] or A[x+1] or A[x+2] or … or A[y]的结果。
现在老板有m次询问,gbx觉得太烦,就要你来解决这个问题。

输入格式:

    第一行一个整数T,表示数据的组数(1<=T<=5)
    对于每组数据,首先读入两个整数n,m ( 1<=n,m<=10^5)表示序列长度和老板询问次数。
    接下来一行读入n个非负整数,表示序列的数,每个数不超过10^9。
    接下来m行,每行两个整数xi,yi,表示询问区间(1<=x<=y<=n)。

输出格式:

对于每次询问,输出一个整数,代表询问区间的or和。

输入样例:

1
6 3
1 2 3 4 5 6
1 3
3 5
2 4

输出样例:

3
7
7

注意:

or是二进制按位取或操作(符号是一个竖线|)。4 or 6 = (100) or (110)=(110)=6

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>
using namespace std;

const int maxn=100000+100;
int N,M,A[maxn][33],sum[maxn][33];

int main(int argc, char* argv[])
{
    int zz=0;
    scanf("%d",&zz);
    for (int test=1; test<=zz; test++)  //while(zz-)
    {
        scanf("%d%d",&N,&M);
        for (int i=1; i<=N; i++)    //N个数据的输入采集
        {
            int x;
            scanf("%d",&x);
            for (int j=0; j<31; j++)
            {
                A[i][j]=(x>>j)&1;   //拆分每个数据的每个位数,二进制,按低到高序排列
                //printf ("%d ",A[i][j]);
            }
            //printf ("#1\n");

        }
        for (int j=0; j<31; j++)
        {
            sum[0][j]=0;    //sum二维数组初始化
            //printf ("%d ",sum[0][j]);
        }
       // printf ("&\n");

        for (int i=1; i<=N; i++)
        {
            for (int j=0; j<31; j++)
            {
                sum[i][j]=sum[i-1][j]+A[i][j];  //将拆散的数据依次按位相加
               // printf ("%d ",sum[i][j]);

            }
           // printf ("#2\n");
        }

        while(M--)  //M次询问
        {
            int x,y;
            scanf("%d%d",&x,&y);    //询问范围数据范围
            int ans=0;
            for (int j=0; j<31; j++)
            {
                if (sum[y][j]-sum[x-1][j]>0)    //从x-1到y位数据中,该位有1出现
                {
                   // printf ("%d %d\n",sum[y][j],sum[x-1][j]);
                    ans|=(1<<j);    //(1<<j)得到该位数据的十进制表示的值
                   // printf ("(1<<j)=%d    ans=%d\n",1<<j,ans);
                }
            }

            printf("%d\n",ans);
        }
    }
    return 0;
}

总结

面对这道题,自己一上来就傻逼的建立数组存储数据,然后循环[x,y]里面的 ‘|’ 运算,但是自己就没有考虑过时限问题。数据范围是10^5,每个数据又是32位,运行达到了2800ms,严重超时。

C :最萌身高差

题目:

   fq进入了ccnu神奇的acm实验室,出去比赛的时候拍合照。fq观察照片发现大家都从左到右站成一排,更神奇的是:他发现实验室队员里出现了最萌身高差。于是,fq翻出了更多的黑历史,想找出每张照片的最萌身高差。
   每张照片,有n个人,所有人从左到右排成一排,身高差定义为相邻两个人的身高差的绝对值,最萌身高差就是指所有身高差最大的那个。

输入格式:

    第一行一个整数T,表示T组数据。
    每组数据首先有一行一个整数,表示人数n(1<=n<=10^4)。
    接下来n行,每行一个字符串和一个整数,表示该位置的人的名字和身高。字符串长度不超过20,整数不超过300

输出格式:

    对于每组数据,输出两行。
    第一行输出一个整数,表示最萌身高差是多少。
     第二行输出两个字符串(中间用一个空格隔开),表示最萌身高差的两个人是谁(按从左到右输出,如果有多个,输出最左边的两个人)

输入样例:

1
6
wh 175
fq 165
wq 170
gbx 165
xb 190
ooc 175

输出样例:

25
gbx xb

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>
using namespace std;

const int maxn=10000+100;
int N,A[maxn];
char name[maxn][25];

int main(int argc, char* argv[])
{
    int zz=0;
    scanf("%d",&zz);
    for (int test=1; test<=zz; test++)
    {
        scanf("%d",&N);
        for (int i=1; i<=N; i++) scanf("%s%d",name[i],&A[i]);
        int ans=-1,k;
        for (int i=1; i<N; i++)
        {
            int ret=abs(A[i]-A[i+1]);
            if (ret>ans) ans=ret,k=i;
        }
        printf("%d\n",ans);
        printf("%s %s\n",name[k],name[k+1]);
    }
    return 0;
}

总结

这是一道简单题,我都能做出来,考的就是字符串的输入输出而已,再就是简单的按序查找。

D:gcd和lcm

题目:

   gbn在教小朋友数论,他在黑板上写了一个题:给出两个正整数x和y,其中gcd(a,b)=x,lcm(a,b)=y,问有多少对满足条件的正整数解(a,b)?
   gcd是两个数的最大公约数,lcm是两个数的最小公倍数。

输入格式:

    第一行一个整数T,表示数据组数。(T<=20)
    接下来T行,每行两个正整数,表示x和y。(1<=x , y<=10^6)

输出格式:

    对于每一个数据,输出一行一个整数g,表示有g对(a,b)满足条件。

输入样例:

3
1 12
3 12
2 24

输出样例:

4
2
4

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>
using namespace std;

#define bll long long
#define dou double
#define For(i,a,b) for (int i=(a),_##i=(b); i<=_##i; i++)
#define Rof(i,a,b) for (int i=(a),_##i=(b); i>=_##i; i--)
#define rep(i,a,b) for (int i=(a),_##i=(b); i<=_##i; i++)
#define rek(i,a,b) for (int i=(a),_##i=(b); i>=_##i; i--)
#define Mem(a,b) memset(a,b,sizeof(a))
#define Cpy(a,b) memcpy(a,b,sizeof(b))

int gcd(int a,int b)
{
    if (b==0) return a;
    return gcd(b,a%b);
}

int main(int argc, char* argv[])
{
    int zz=0;
    scanf("%d",&zz);
    for (int test=1; test<=zz; test++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if (y%x!=0) //公因数和公倍数互质
        {
            printf("0\n");
            continue;
        }
        int r=y/x;  //a,b两数都除去公因数,较小的数的范围小于sqrt(r),或者说小于max(k1,k2)*x;
        int ans=0;
        for (int i=1; i*i<=r; i++)
            if (r%i==0 && gcd(i,r/i)==1)    //i是r的因数,同时i与r/i互质
            {
                ans++;
                if (i!=r/i)  //a!=b,数据位置可以颠倒
                    ans++;
            }
        printf("%d\n",ans);
    }
    return 0;
}

总结:

x=gcd(a,b);

y=lcm(a,b)=a*b/gcd(a,b);

x * y=a * b;

a=k1 * x,b=k2 * x(k1,k2互质,);

y=k1 * k2 * x;

自己的傻逼方法当然超时限了,数据范围是10^6,自己也一直没有找到循环的范围是i*i<=r;

E:战火纷飞

题目:

    一天WH睡醒之后发现自己竟然穿越到了一个战火纷飞的朝代,而且他还是一个国君,尽管如此不可思议,但是WH内心毫无波动,甚至还想睡觉。这时候一个御用太监递上了一份册子,WH定睛一看,这是现在各个国家的战斗力表,WH知道,只要战斗力比自己低或者相等的国家就能打败他们,而且如果现在他去攻打一个国家战斗力只有自己国家的一半或者一半以下的国家,那么他将毫不费力地拿下这个国家,并且被战败的这个国家的战斗力将会全部加到自己国家上,但是如果他去攻打一个国家战斗力超过自己国家战斗力一半的国家,打败这个国家之后,自己国家的战斗力会增加上战败国战斗力的一半,现在由于WH刚睡醒所以不想看这个战斗力表,所以他想把这个战斗力表给你,让你算算他最终能不能打败所有国家,如果能输出他的国家最终能达到的最高的战斗力,如果不能,输出-1。(文中所有的除法计算若不能整除,则向下取整)
    国家的数目n的范围为[1, 10000], 该战斗力表上所有国家的战斗力范围都在[1,INT_MAX]内。
    注意:战斗力相等的国家也可以打赢。

Input:

多组数据。
每组数据的第一行为一个数字n,表示有n个国家。接下来的一行有n个数字,代表n个国家的战斗力,其中第一个数为WH所在国家的战斗力。

Output:

对于每组数据,输出一个数:若WH能够打败所有国家则输出他的国家能达到的最大的国家战斗力,如果不能输出-1。

Sample Input

5
9 2 10 4 13
5
5 9 8 14 2

Sample Output

26
-1

Hint:

第一组样例解释:先把战斗力为4的国家打败,自己国家的战斗力上升为13,再把战斗力为2的国家打败,自己国家的战斗力上升为15,再把战斗力为10的国家打败,自己国家的战斗力上升为20,再把战斗力为13的国家打败,自己国家的战斗力上升为26
第二组样例解释:先把战斗力为2的国家打败,自己国家的战斗力上升为7,无法继续打败其他国家。

总结:

个人的思路是,先将国家战力值排个序,依次打下去,知道打完或者打不赢。当然这是多么的单纯啊。这个世界慢慢的恶意告诉我,当碰到10 6 8这个情况的时候,先打8更好一些,然后就以为应该每次打完战力值一半及一下之后,就选择获益最高的(打8获得4,打6获得3),但可恶的世界又告诉我,碰到20 12 13时 先打12更好一些,这里要是有表情,真想掩面痛哭啊、、、然后蠢蠢的我就不知道能干嘛呢、、

时间: 2024-10-16 18:05:14

day_7-acm 周赛总结(1)的相关文章

梦想终于起航

刚刚看完罗添翼学长(某种情结还是称作Xenny)的博客,感触很深. 决定写下人生第一篇博客(一篇回忆录罢了): (不自觉在句尾打下了:海星) 不得不说2018对我来说是很重要的一年,刚刚参加完高考,结果不尽人意,人生难得的打击也算作是一种磨练.误打误撞来到swpu,也正是梦想起航的地方. 说实话,上了大学开始,这才真正打破了我对大学的各种美好的期盼QWQ. 大学刚刚开始忙完了各种安顿工作,就考虑如何让自己在大学里学到真正的东西,不荒废大学四年时光. 在学校社团招人的时候,加入了一个爱心社团,也去

ACM训练联盟周赛 C题 Alice和Bob的Nim游戏

题目描述 众所周知,Alice和Bob非常喜欢博弈,而且Alice永远是先手,Bob永远是后手. Alice和Bob面前有3堆石子,Alice和Bob每次轮流拿某堆石子中的若干个石子(不可以是0个),拿到所有石子中最后一个石子的人获胜.这是一个只有3堆石子的Nim游戏. Bob错误的认为,三堆石子的Nim游戏只需要少的两堆的石子数量加起来等于多的那一堆,后手就一定会胜利.所以,Bob把三堆石子的数量分别设为 {k,4k,5k}(k>0). 现在Alice想要知道,在k 小于 2^n 的时候,有多

2020-3-14 acm训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019 解题报告+补题报告

2020-3-15比赛解题报告+2020-3-8—2020-3-15的补题报告 2020-3-15比赛题解 训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019  A建筑(模拟) 耗时:3ms 244KB 建筑 你哥哥在最近的建筑问题突破大会上获得了一个奖项 并获得了千载难逢的重新设计城市中心的机会 他最喜欢的城市奈梅根.由于城市布局中最引人注目的部分是天际线, 你的兄弟已经开始为他想要北方和东方的天际线画一些想法

ACM团队周赛题解(2)

拉了CF583和CF486的两套div2题目 还是先贴宏定义部分 #define MAXN 1000000+5#define MOD 1000000007#define PI (acos(-1.0))#define EPS 1e-6#define MMT(s,a) memset(s, a, sizeof s)#define GO(i,a,b) for(int i = (a); i < (b); ++i)#define GOE(i,a,b) for(int i = (a); i <= (b);

ACM团队周赛题解(3)

940和822两套div.2 老规矩 #define MAXN 1000000+5#define MOD 1000000007#define PI (acos(-1.0))#define EPS 1e-6#define MMT(s,a) memset(s, a, sizeof s)#define GO(i,a,b) for(int i = (a); i < (b); ++i)#define GOE(i,a,b) for(int i = (a); i <= (b); ++i)#define OG

3xian 退役帖------acm精神世界的捍卫者

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------最后一天,漫天飘起了雪花,假装欢送我离去. 这次WF之战不太顺利,早期的C题大概花了1秒钟构思,然而由于输出格式多了一个空格直到两个半小时才逃脱W

2015 年 JXNU_ACS 算法组寒假第二次周赛

2015 年 JXNU_ACS 算法组寒假第二次周赛 比赛链接:http://acm.hdu.edu.cn/diy/contest_show.php?cid=26246 Start Time : 2015-02-01 13:00:00 End Time : 2015-02-01 17:30:00 终榜:http://acm.hdu.edu.cn/diy/contest_ranklist.php?cid=26246&page=1 这次比赛考查的知识都很基础,甚至还有几道就是C语言基础(比如1006

周赛 POJ 3934 Queue

Description Linda is a teacher in ACM kindergarten. She is in charge of n kids. Because the dinning hall is a little bit far away from the classroom, those n kids have to walk in line to the dinning hall every day. When they are walking in line, if a

acm 一年总结

首先是大一的一段简短历史,和其他人不太一样,刚上大一的我等于是刚刚接触电脑,开始下载程序啦,安装系统了,电脑出个小问题啦自己都不会解决,然后大一还开了一门叫做c语言的课程,顿时傻逼了,当时也不用功,大概每一周去一次机房,绝大多数的时间是花在了学数学上,因为我认为我应该转专业去学物理,然后就这样颓废了将近一年的时间,在大一下学期快期末考试的时候,听说鸡哥要搞acm,我当时想了想桃他们思维这么活跃应该就是和这个有关,于是乎没想别的,就是干. 开始的时候刷了不少字符串的题目(其实用STL几行就ac的题

转3xian之所在 (一位ACM大牛的博文)

3xian的经历和见解...我深思... 最后一天,漫天飘起了雪花,假装欢送我离去. 这次WF之战不太顺利,早期的C题大概花了1秒钟构思,然而由于输出格式多了一个空格直到两个半小时才逃脱Wrong Answer的纠缠.还好lynncui在期间独挡一面过掉D.最终成绩不好,然而没有遗憾,从不遗憾. 相比之下,来自全球的队伍让我看到了很强大的实力,每一道题都有人过,包括SJTU欺骗性提交的H都被人干掉了.身为地球人我感到自豪. WF之旅很奢华(Sample: 1300一晚的酒店,99一顿的早餐),活