套题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\n",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\n",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

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2016-09-03 17:22  pandaB  阅读(261)  评论(0编辑  收藏  举报