zoukankan      html  css  js  c++  java
  • 套题T4

    Problem 1 无聊的gcd(gcd.c/cpp/pas)

    话说出题人不会被查水表吧。

    简单的问题描述:从N个正整数里面取出K个数的最大公因数最大是多少。(请将答案乘上k之后输出哦,谢谢合作。)

    输入格式

    第一行两个正整数N,K。

    第二行n个正整数

    输出格式

    输出一个正整数表示最大的最大公因数。

    样例输入

    3 1

    1 2 3

    样例输出

        3

    数据说明

    对于30%的数据,保证k≤n≤20。

    对于50%的数据,保证输入中所有数小于5000。

    对于100%的数据,保证输入中所有数小于500000,k≤n。


     

    0表示不取 1表示取

    用i的二进制表示状态  比如i=10101表示取1,3,5    i=00110表示取3,4

    然后for一遍,tmp表示i的二进制当中1的数量
    如果1有k个
    那么i代表的状态选了k个数

    for一遍把i表示的状态取了的数的gcd取出来

    最后统计ans

     

    #include <cstdio>
    #include<iostream>
    using namespace std;
    const int Maxn = 40;
    
    int a[Maxn],n,k,ans=0;
    
    int gcd(int a,int b) 
    {
        return b ? gcd(b,a%b) : a;
    }
    
    int max(int a,int b) 
    {
        return a < b ? b : a ;
    }
    
    int main() 
    {
        scanf("%d%d",&n,&k);
        for(int i=0;i<n;++i)scanf("%d",&a[i]);//读入 
        for(int i=1;i<(1<<n);++i) 
        {
            int tmp = 0;
            for(int j=0;j<n;++j) 
            {
                if(i&(1<<j))    ++tmp;
                //tmp表示选了几个数 
            }
    //        printf("i = %d : tmp = %d
    ",i,tmp);
            if(tmp==k)//如果选了k个 
            {
                tmp=-1;
                for(int j=0;j<n;++j) 
                {
                    if(i&(1<<j)) 
                    {
                        if(tmp==-1) tmp=a[j];
                        else tmp=gcd(a[j],tmp);
                    }
                }
                ans = max(ans,tmp);
    //            printf("ans : %d
    ",ans);
            }
        }
        printf("%d",ans*k);
        puts("");
        return 0;
    } 
    QAQ数论好烦啊

    如果i&(1<<j) == 1的话那么i的第j位就是1 

    因为1<<j是...001000...的形式存在,所以和 i 与起来,要是 i 这一位是 1 , 就是1,i 这一位是0,就是0

     所以 i&(1<<j) 表示 i 在二进制下的第 j 位

     

     因为1<<0 = 1 这时候j=0 如果从1存的话就变成1<<1 = 2 那就时间复杂度*2 所以从0开始读

     


     

    首先所有输入数字不大于50W,那么我们开一个50W的数组,记下每个数字出现多少次

    然后就有一些有意思的事情发生了

    我们从小到大枚举答案 每个答案x,判定可行的方法就是遍历每一个x的倍数

    那么只要把所有x的倍数统计一下有多少看看是不是大于等于k就好了

    如果我选的是这k个x的倍数,那么我们不就知道答案至少是x了

     

     

     

     

     

     

     

     

     

     


    Problem 2 虫洞(wormhole.cpp/c/pas)

    【题目描述】

    John在他的农场中闲逛时发现了许多虫洞。虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前)。John的每个农场有M条小路(无向边)连接着N (从1..N标号)块地,并有W个虫洞(有向边)。其中1<=N<=500,1<=M<=2500,1<=W<=200。 现在John想借助这些虫洞来回到过去(出发时刻之前),请你告诉他能办到吗。 John将向你提供F(1<=F<=5)个农场的地图。没有小路会耗费你超过10000秒的时间,当然也没有虫洞回帮你回到超过10000秒以前。

    【输入格式】

    * Line 1: 一个整数 F, 表示农场个数。

    * Line 1 of each farm: 三个整数 N, M, W。

    * Lines 2..M+1 of each farm: 三个数(S, E, T)。表示在标号为S的地与标号为E的地中间有一条用时T秒的小路。

    * Lines M+2..M+W+1 of each farm: 三个数(S, E, T)。表示在标号为S的地与标号为E的地中间有一条可以使John到达T秒前的虫洞。

    【输出格式】

    * Lines 1..F: 如果John能在这个农场实现他的目标,输出"YES",否则输出"NO"。

    【样例输入】

    2

    3 3 1

    1 2 2

    1 3 4

    2 3 1

    3 1 3

    3 2 1

    1 2 3

    2 3 4

    3 1 8

    【样例输出】

    NO

    YES


    1.一个点如果经过一个环以后dis一直在变小,那么显然这个环是负环
    2.如果没有负环一个点最多进队n次(每条只想j的边都维护一遍dis)

    所以vis记成int,int vis[Maxn];

    while(!q.empty()) 

    Problem 3 机器人(robot.cpp/c/pas)

    【题目描述】

    早苗入手了最新的Gundam模型。最新款自然有着与以往不同的功能,那就是它能够自动行走,厉害吧。

    早苗的新模型可以按照输入的命令进行移动,命令包括‘E’、‘S’、‘W’、‘N’四种,分别对应东南西北。执行某个命令时,它会向对应方向移动一个单位。作为新型机器人,它可以执行命令串。对于输入的命令串,每一秒它会按命令行动一次。执行完命令串的最后一个命令后,会自动从头开始循环。在0时刻时机器人位于(0,0)。求T秒后机器人所在位置坐标。

    【输入格式】

    1行:一个字符串,表示早苗输入的命令串,保证至少有1个命令

    2行:一个正整数T

    【输出格式】

    2个整数,表示T秒时,机器人的坐标。

    【样例输入】

    NSWWNSNEEWN

    12

    【样例输出】

    -1 3

    【数据范围】

    对于60%的数据 T<=500,000 且命令串长度<=5,000

    对于100%的数据 T<=2,000,000,000 且命令串长度<=5,000

    【注意】

    向东移动,坐标改变改变为(X+1,Y);

    向南移动,坐标改变改变为(X,Y-1);

    向西移动,坐标改变改变为(X-1,Y);

    向北移动,坐标改变改变为(X,Y+1); 


     由于t特别大然后操作序列最长只有5000

     就先做一遍操作序列,看看做完一整个序列之后,x和y是变化量是多少,并记录这个变化量

    用t除以长度,剩下的就是取模了就是t%长度  就知道要做到哪里了

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    char ch[5005];
    int t,nn=0;
    int xx=0,yy=0;
    int x=0,y=0;
    int main()
    {
        scanf("%s%d",ch+1,&t);
        int n=strlen(ch+1);
        for(int i=1;i<=n;++i)
        {
            if(ch[i]=='N')yy++;
            if(ch[i]=='S')yy--;
            if(ch[i]=='W')xx--;
            if(ch[i]=='E')xx++;
        }
        nn=t/n;
        t%=n;
        for(int i=1;i<=t;++i)
        {
            if(ch[i]=='N')y++;
            if(ch[i]=='S')y--;
            if(ch[i]=='W')x--;
            if(ch[i]=='E')x++;
        }
        cout<<x+xx*nn<<" "<<y+yy*nn;
        puts("");
        return 0;
    }
    模拟也要动脑子QAQ

     

     

     

     

     

  • 相关阅读:
    C#计算两个时间年份月份天数(根据生日计算年龄)差,求时间间隔
    C#四舍五入保留一位小数
    给Editplus去掉.bak文件
    $().each() 与 $.each()解析
    VS 2013+Qt 5.4.1
    HDU 5228 ZCC loves straight flush( BestCoder Round #41)
    产品经理的修炼:如何把梳子卖给和尚
    c++ STL unique , unique_copy函数
    linux定时备份mysql数据库文件
    Python——异常基础
  • 原文地址:https://www.cnblogs.com/gc812/p/5837588.html
Copyright © 2011-2022 走看看