Contest1306 - 浙江中医药大学寒假抗疫训练赛一

话不多说开整;
难度排行:A>B>F>E>G>D>C

Problem A: Not A + B

Description
输入两个非负整数a, b,你需要输出一个最小的正整数c,满足c≠a + b。
Input
第一行包含一个正整数T(1 ≤ T ≤ 10000),表示测试数据的组数。
每组测试数据包含一行两个整数a, b(0 ≤ a, b ≤ 10000)。
Output
对于每组测试数据,输出一行一个整数,即你找到的c。
Sample Input
3
1 2
3 4
5 6
Sample Output
1
1
1
思路:输入a,b的和不是1就输出2要不然就输出1

Problem B: 混合饮料

Description
小Q 非常喜欢喝茶和牛奶的混合饮料,这种饮料严格按照下述规则配置而成:
一开始,杯子里的饮料由茶和牛奶1 比1 混合而成。之后,小Q 会依次进行n 次操作,第i 次操作由大写字母“H”或者“M”表示。如果第i 次操作是“H”,那么小Q 会喝掉半杯饮料,然后倒入半杯茶并混合均匀;如果第i 次操作是“M”,那么小Q 会喝掉半杯饮料,然后倒入半杯牛奶并混合均匀。
小Q 进行完了n 次操作,他想知道他喝掉的茶和牛奶哪种成分占的比例更多,请写一个程序回答小Q 的问题。
Input
第一行包含一个正整数T(1 ≤ T ≤ 10000),表示测试数据的组数。
每组数据第一行包含一个正整数n(1 ≤ n ≤ 106),表示操作个数。
第二行包含一个长度为n 的字符串,从左往右表示每个操作。
输入数据保证Σn ≤ 3 × 106。
Output
对于每组数据,输出一行,若茶更多,输出“H”;若牛奶更多,输出“M”;若茶和牛奶一样多,输出“HM”。
Sample Input
1
5
HMHHM
Sample Output
H

思路:按题意模拟;

#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false), cin.tie(0)
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int main()
{
    IO;
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        string s;
        cin>>n>>s;
        double mil=1,tea=1;
        double mt=0,tt=0;
        for(int i=0; i<n; i++)
        {
            mt+=mil/2;
            tt+=tea/2;
            if(s[i]=='M')
            {
                mil=mil/2+0.5;
                tea=tea/2;
            }
            else
            {
                tea=tea/2+0.5;
                mil=mil/2;
            }
        }
        if(mt>tt)
        {
            cout<<"M"<<endl;
        }
        else if(mt<tt)
        {
            cout<<"H"<<endl;
        }
        else
        {
            cout<<"HM"<<endl;
        }
    }
    return 0;
}

Problem C: 黑暗长廊

Description
深夜,小Q 走在一条黑暗的长廊上。长廊可以视为一条数轴。在长廊上有n 盏灯,从左往右依次
编号为1 到n,第i 盏灯坐标为xi,可以照亮数轴上[xi − ri, xi + ri] 的部分(包含两边界)。如果一个
位置没有被任何灯照亮,那么怕黑的小Q 是不敢去那里的。
小Q 可以在长廊上往左或者往右走。如果他的位置与某盏灯重合,他可以选择打开或者关闭这盏
灯。一开始,小Q 的位置与第1 盏灯重合,第1 盏灯处于打开状态,其它所有灯都处于关闭状态。小
Q 希望在灯光下走到第n 盏灯的位置,并且使得第n 盏灯处于打开状态,其它所有灯都处于关闭状态。
请写一个程序,帮助小Q 找到路程最短的路线,或告诉他这是不可能的。

Input
第一行包含一个正整数T(1 ≤ T ≤ 2000),表示测试数据的组数。
每组数据第一行包含一个正整数n(2 ≤ n ≤ 100000),表示灯的数量。
接下来n 行, 每行两个正整数xi, ri, 分别表示每盏灯的位置和灯光半径, 其中
1 ≤ x1 < x2 < x3 < ::: < xn ≤ 109,1 ≤ ri ≤ 109。
输入数据保证Σn ≤ 300000。
Output
对于每组数据输出一行一个整数,即最短的总路程,若无解请输出“-1”。
Sample Input
4
5
1 5
3 1
4 9
7 8
8 4
2
1 1
10 10
2
1 10
10 8
2
1 1000000000
1000000000 999999999
Sample Output
21
-1
-1
2999999997

思路:根据题目的描述就是要在X轴上从1走到N并且开关灯,那么我们可不可以理解为从1开始走一路开灯到N,然后从N回来一路关灯(除了N);
那不就是一个遍历所有点的过程,记录当前最大可达到的的边缘,然后更新可达到的点和边缘,回来的时候不关N的灯就可以了

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100010;
int T,n,i,mx,f[N];
struct P
{
    int x,r;
} a[N];
long long solve()
{
    scanf("%d",&n);
    for(i=1; i<=n; i++)scanf("%d%d",&a[i].x,&a[i].r);
    i=1;
    mx=a[1].x+a[1].r;
    while(i<n&&a[i+1].x<=mx)
    {
        i++;
        mx=max(mx,a[i].x+a[i].r);
    }
    if(i<n)return -1;
    for(i=1; i<=n; i++)f[i]=a[i].x-a[i].r;
    for(i=n-1; i; i--)f[i]=min(f[i],f[i+1]);
    for(i=1; i<n; i++)if(f[i+1]>a[i].x)return -1;
    return 3LL*(a[n].x-a[1].x);
}
int main()
{
    scanf("%d",&T);
    while(T--)printf("%lld\n",solve());
}

Problem D: Factorization

Description
You are given a positive integer n(n > 1). Consider all the different prime divisors of n. Each of
them is included in the expansion n into prime factors in some degree.
Assume n = p1e1 p2e2… pmem , where pi are different prime divisors of n and ei ≥ 1. Your task is to find
the greatest common divisor of e1,e2,…, em.
Input
The first line of the input contains an integer T(1 ≤ T ≤ 10000), denoting the number of test cases.
In each test case, there is only one integer n(2 ≤ n ≤ 1018).
Output
For each test case, print a single line containing an integer, denoting the answer.
Sample Input
3
4
6
36
Sample Output
2
1
2

题面:这道题题意是 ,几个素数的几次幂相乘,求幂次的最大公约数。
比如108=427=2233,max=2;
思路:一开始我想到另外一道题去了;长得好像但是思路不一样,
贴一下链接:杭电2019多校第四场 HDU-6623 Minimal Power of Prime
就很像但是一个求最大一个求最小我就突然一下子蒙蔽了
这里说一下这题的思路:就是在这里插入图片描述
可以暴力出来;;

#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
int Case;
ll n,i;
inline ll cal(ll a,ll b)
{
    ll t=1;
    while(b--)
    {
        if(t>n/a)return n+1;
        t*=a;
    }
    return t;
}
inline bool check(ll n,ll k)
{
    ll t=pow(n,1.0/k);
    t-=3;
    if(t<1)t=1;
    while(cal(t+1,k)<=n)t++;
    return cal(t,k)==n;
}
int main()
{
    scanf("%d",&Case);
    while(Case--)
    {
        scanf("%lld",&n);//n>1
        for(i=60; i>1; i--)if(check(n,i))break;
        printf("%lld\n",i);
    }
}

Problem E: Problem F. Numbairs

Description
Consider number of the form aa…a where a is a positive integer that can appear in the notation
twice or more. Let us call such numbers numbairs (which stands for number + stairs). For instance,
both 27 = 33 and 16 = 222 are numbairs. Number 1 is, too, a numbair since 1 = 11. Find out how many
numbairs there are between 1 and a number n given to you (inclusive).
Input
The first line of the input contains an integer T(1 ≤ T ≤ 10000), denoting the number of test cases.
In each test case, there is an integer n(1 ≤ n ≤ 109).
Output
For each test case, print a single line containing an integer, denoting the number of numbairs not
exceeding n.
Sample Input
1
5
Sample Output
2
题面:有一种幂次的幂次的数 ex.11,2(2) 或者是二的二的二的二次
让你判断1到n有几个,
思路 预处理,加检索就好了;
可以判断出最大的MM M==9 控制下上限就好了

#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false), cin.tie(0)
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
vector<ll>num;
ll qpow(ll a, ll b)
{
    ll res = 1;
    while (b)
    {
        if (b&1)res = res*a;
        a = a*a;
        b >>= 1;
    }
    return res;
}
void init()
{
    num.push_back(1);
    ll tmp;
    for(int i=2; i<=10; i++)
    {
        tmp=i;
        while(pow(i,tmp)<(double)(1e9+10))
        {
            tmp=pow(i,tmp);
            num.push_back(tmp);
        }
    }
    return ;
}
int main()
{
    init();
    sort(num.begin(),num.end());
    IO;
    int t;
    cin>>t;
    while(t--)
    {
        int n,cnt=0;
        cin>>n;
        for(int i=0; i<num.size(); i++)
        {
            if(n>=num[i])cnt++;
        }
        cout<<cnt;
        if(t)cout<<endl;
    }
    return 0;
}

Problem F: 序列归并

Description
Alice 和Bob 正在对两个序列a1, a2,…, an 和b1, b2,…,bm 进行操作。
Alice 首先需要将它们归并成一个长度为n + m 的序列c1,c2,…,cn+m。即将序列a 和b 合并成一个序列c,但不改变a 和b 的顺序。显然可能有许多许多种不同的归并结果。
Bob 需要在Alice 完成归并之后, 选择一对l,r, 满足1 ≤ l ≤ r ≤ n + m, 并使得score = cl + cl+1 + cl+2 + …+ cr−1 + cr 尽可能地大。
不同的归并结果以及不同的选择l,r 的方式都会使得最后score 的值不尽相同,请问score 最多能达到多少呢?

Input
第一行包含一个正整数T(1 ≤ T ≤ 10),表示测试数据的组数。
每组测试数据第一行包含两个正整数n,m(1 ≤ n,m ≤ 100000),分别表示序列a 和序列b 的长度。
第二行包含n 个整数a1, a2,…, an(−109 ≤ ai ≤ 109)。
第三行包含m 个整数b1,b2,…, bm(−109 ≤ bi ≤ 109)。
输入数据保证a 和b 中至少有一个正数。
Output
对于每组测试数据,输出一行一个整数,即score 的最大值。
Sample Input
1
2 3
1 5
3 -1 -1
Sample Output
9

思路:分别找连续最大和不懂得小朋友去看一下1007 Maximum Subsequence Sum
这是一道PTA基础题目贪心思路;(基础啊!)

#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false), cin.tie(0)
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn=1e5+10;
ll a[maxn],b[maxn];
ll f(ll A[], int N)
{
    ll tmp, t, i;
    tmp = t = 0;
    for( i = 0; i < N; i++ )
    {
        tmp += A[i];
        if( tmp > t )
            t = tmp;
        else if( tmp < 0 )
            tmp = 0;
    }

    return t;
}
int main()
{
    IO;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0; i<n; i++)scanf("%lld",&a[i]);
        for(int i=0; i<m; i++)scanf("%lld",&b[i]);
        ll ans=f(a,n)+f(b,m);
        printf("%lld",ans);
        if(t)printf("\n");
    }
    return 0;
}


Problem G: Least Common Multiple

Description
In arithmetic and number theory, the least common multiple of two integers a and b, usually denoted by LCM(a, b), is the smallest positive integer that is divisible by both a and b.

The LCM of more than two integers is also well-defined: it is the smallest positive integer that is divisible by each of them.

You are given n n n positive integers a_1,a_2,…,a_n, please find the LCM of them.
Input
The first line of the input contains an integer T(1 ≤ T ≤ 10), denoting the number of test cases.

In each test case, there is one integer n(2 ≤ n ≤ 15) in the first line.

In the second line, there are n integers a_1,a_2,…,a_n(1 ≤ a_i ≤ 10^18).
Output
For each test case, print a single line containing an integer, denoting the LCM. Since the answer can
be extremely large, please print it modulo 10^9 + 7 instead.
Sample Input
3
2
4 6
3
7 8 9
2
1000000009 1000000009
Sample Output
12
504
2
思路难度不大;求个n个数 的 小公倍数
取余不就好了;
来个丁丁的java版本;
思路就在下面了:
代码很短的;
注意取模;

import java.math.BigInteger;
import java.util.Scanner;

public class Main
{

    public static void main(String[] args)
    {
        Scanner scanner = new Scanner(System.in);
        int T = scanner.nextInt();
        BigInteger Big;
        while ((T--) != 0)
        {
            int n;
            n = scanner.nextInt();
            BigInteger x = BigInteger.ONE;
            for (int i = 0; i < n; i++)
            {
                Big = scanner.nextBigInteger();
                x = x.multiply(Big).divide(x.gcd(Big));
            }
            System.out.println(x.mod(new BigInteger("1000000007")));
        }

    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值