【比赛重练】◆AtCoder◆ Peterzavodsk Contest 001

◆AtCoder◆ Peterzavodsk Contest 001


□目录□


□背景□

这个比赛是老师从AtCoder里重新拿出来做的,所以可能比较旧了。但是我并没有做这个比赛里所有的题(好像是有9道题),所以今天在这篇Blog里就只讲一下前3道题。


A- Two Integers

◇原题◇

-(AtCoder 3908)
Time limit : 2sec / Memory limit : 256MB
Score : 100 points
Problem Statement
You are given positive integers X and Y. If there exists a positive integer not greater than 1018 that is a multiple of X but not a multiple of Y, choose one such integer and print it. If it does not exist, print −1.
Constraints
1X,Y109 1 ≤ X , Y ≤ 10 9
X and Y are integers.
Input
Input is given from Standard Input in the following format:

X Y

Output
Print a positive integer not greater than 1018 10 18 that is a multiple of X but not a multiple of Y, or print −1 if it does not exist.
Samples

Sample 1Sample 2
Sample Input 86 8 6 33 3 3
Sample Output 16 16 1 − 1

Sample 1: example, 16 is a multiple of 8 but not a multiple of 6.
Sample 2: multiple of 3 is a multiple of 3.

◇翻译◇

给出2个整数X、Y( 1X,Y108 1 ≤ X , Y ≤ 10 8 ),求是否存在一个小于 1018 10 18 的数,使得它能被X整除但不能被Y整除。若存在,输出这个数,否则输出-1。

◇解析◇

这可以说是这场比赛里最简单的题了。其实进行简单的分析——如果 y|x y | x ,则令 x=ky x = k y ,所以必存在 ax=aky a x = a k y ,所以就一定无解(输出-1);如果 y/|x y ⧸ | x ,则……就输出 x ,因为y不整除x啊。

◇源代码◇

/*Lucky_Glass*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
    int x,y;
    scanf("%d%d",&x,&y);
    if(x%y==0){puts("-1");return 0;}
    printf("%d\n",x);
    return 0;
}

B- Two Arrays

◇原题◇

-(AtCoder 3909)
Time limit : 2sec / Memory limit : 256MB
Score : 300 points
Problem Statement
You are given two integer sequences of length N: a1,a2,..,aNandb1,b2,..,bN a 1 , a 2 , . . , a N a n d b 1 , b 2 , . . , b N . Determine if we can repeat the following operation zero or more times so that the sequences a and b become equal.
Operation: Choose two integers i and j (possibly the same) between 1 and N (inclusive), then perform the following two actions simultaneously:

Add 2 to ai.
Add 1 to bj.

Constraints
1N10000 1 ≤ N ≤ 10 000
0ai,bi109(1iN) 0 ≤ a i , b i ≤ 109 ( 1 ≤ i ≤ N )
All input values are integers.
Input
Input is given from Standard Input in the following format:

N
a1 a2 .. aN
b1 b2 .. bN

Output
If we can repeat the operation zero or more times so that the sequences a and b become equal, print Yes; otherwise, print No.
Samples

Sample 1Sample 2Sample 3
Input 31 2 35 2 2 3 1   2   3 5   2   2 53 1 4 1 52 7 1 8 2 5 3   1   4   1   5 2   7   1   8   2 52 7 1 8 23 1 4 1 5 5 2   7   1   8   2 3   1   4   1   5
Output Yes Y e s No N o No N o

Sample 1:
For example, we can perform three operations as follows to do our job:
First operation: i=1 and j=2. Now we have a={3,2,3}, b={5,3,2}.
Second operation: i=1 and j=2. Now we have a={5,2,3}, b={5,4,2}.
Third operation: i=2 and j=3. Now we have a={5,4,3}, b={5,4,3}.

◇翻译◇

第一行给出N,然后给出两个集合 A={a1,a2,...,aN}  B={b1,b2,...,bN} A = { a 1 , a 2 , . . . , a N }     B = { b 1 , b 2 , . . . , b N }
现在可以进行一些操作,具体为同时选择A中一个元素 ai a i 和B中一个元素 bj b j ,并给 ai a i 加2,给 bj b j 加1。求是否能通过数次操作,使A、B相同(不限操作次数)。
若可以,输出”Yes”;否则输出”No”。

◇解析◇

不难发现,对于两个集合中的相同位置,每次操作都能够使 aibi a i − b i 大1。所以如果 aibi<0 a i − b i < 0 ,则一定可以通过 biai b i − a i 次操作使 ai a i bi b i 相同;否则就需要单独对 ai a i 进行操作(此时需要另找一个 bj b j ),进行 aibi a i − b i 次操作使 ai=bi a i = b i

所以我们统计A的总和 sum_a 和B的总和 sum_b 。当 suma>sumb s u m a > s u m b 时,如果我们进行操作,则 sumasumb=sumasumb+1 s u m a ′ − s u m b ′ = s u m a − s u m b + 1 ,所以仍然无法得到答案(如果 sumasumb s u m a ≠ s u m b ,则A、B一定不相等),这就是一种无解情况。

suma<=sumb s u m a <= s u m b
①如果有 ai>bi a i > b i ,则需要在另外找一组 aj<bj a j < b j ,同时对 bi b i aj a j 进行操作,直到 ai=bi a i = b i 或者 ajbj a j ≥ b j ,此时再进行操作就没有意义,因为只会让 (biai) ( b i − a i ) 增大或者使 (ajbj) ( a j − b j ) 增大;
②如果不存在 ai>bi a i > b i ,则A、B直接相等,或者存在 ai<bi a i < b i ,我们可以证明此种情况一定有解——设 biai=k b i − a i = k ,若对 ai a i bi b i 进行操作,则 biai=biai1=k1 b i ′ − a i ′ = b i − a i − 1 = k − 1 ,则进行k次操作,就可以使 biai=k1k=0 b i ′ − a i ′ = k − 1 · k = 0 。所以对每对 ai<bi a i < b i 进行 (biai) ( b i − a i ) 次操作,就可以使A、B相等。

综上,我们统计 Sum1=ai>bi(aibi) S u m 1 = ∑ a i > b i ( a i − b i ) Sum2=ai<bi(biai) S u m 2 = ∑ a i < b i ( b i − a i ) 。所以当 Sum1>Sum2 S u m 1 > S u m 2 时,则无解;否则有解。

◇源代码◇

/*Lucky_Glass*/
#include<cstdio>
#include<algorithm>
int n,A[10005],B[10005];
long long sumA,sumB;
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&A[i]);
    for(int i=0;i<n;i++) scanf("%d",&B[i]);
    for(int i=0;i<n;i++)
    {
        if(A[i]-B[i]>0)
            sumA+=A[i]-B[i];
        else
            sumB-=(A[i]-B[i])/2;
    }
    printf("%s\n",sumA<=sumB?"Yes":"No");
    return 0;
}

C - Vacant Seat

◇原题◇

-(AtCoder 3910)
Time limit : 2sec / Memory limit : 256MB
Score : 500 points

Problem Statement
This is an interactive task.

Let N be an odd number at least 3.
There are N seats arranged in a circle. The seats are numbered 0 through N−1. For each i (0≤i≤N−2), Seat i and Seat i+1 are adjacent. Also, Seat N−1 and Seat 0 are adjacent.

Each seat is either vacant, or oppupied by a man or a woman. However, no two adjacent seats are occupied by two people of the same sex. It can be shown that there is at least one empty seat where N is an odd number at least 3.

You are given N, but the states of the seats are not given. Your objective is to correctly guess the ID number of any one of the empty seats. To do so, you can repeatedly send the following query:

Choose an integer i (0≤i≤N−1). If Seat i is empty, the problem is solved. Otherwise, you are notified of the sex of the person in Seat i.

Guess the ID number of an empty seat by sending at most 20 queries.
Constraints

N is an odd number.
3≤N≤99 999

Input and Output
First, N is given from Standard Input in the following format:

N

Then, you should send queries. A query should be printed to Standart Output in the following format. Print a newline at the end.

i

The response to the query is given from Standard Input in the following format:

s

Here, s is Vacant, Male or Female. Each of these means that Seat i is empty, occupied by a man and occupied by a woman, respectively.
Notice

Flush Standard Output each time you print something. Failure to do so may result in TLE.
Immediately terminate the program when s is Vacant. Otherwise, the verdict is indeterminate.
The verdict is indeterminate if more than 20 queries or ill-formatted queries are sent.

Sample
In this sample, N=3, and Seat 0, 1, 2 are occupied by a man, occupied by a woman and vacant, respectively.

InputOutput
3012 3 0 1 2 MaleFemaleVacant M a l e F e m a l e V a c a n t

◇翻译◇

这是一道互动式题目。
有一张圆桌,有n(n为奇数)个座位,其中有一些座位是空的。座位按照 0~n-1 编排(0与n-1相邻),已知相邻的座位上不可能坐相同性别的人。你可以进行最多20次提问,格式为

i

接下来将会给出座位i的人的性别(Male或者Famale)或者是一个空座位(Vacant),如果发现座位i是空座位,则结束程序。注意,当你询问超过20次,你将会得到”TLE”。

◇解析◇

这算是一种新题型吧,特殊题型就有特殊版,所以……版先上来:

int Query(int ans) //ans是你想要询问的值
{
    char ret[20];
    printf("%d\n", ans);
    fflush(stdout);
    scanf("%s", ret);
    if(ret[0] == 'V') return 2;
    return ret[0] == 'M' ? 1 : 0;
}

因为n最大99999,但是只能询问不超过20次。所以很容易想到用二分查找。
作为一个OIer,我们一定要相信——一定要读完题目,既然要读完题目,我们就会注意到:

n是奇数

???为什么是奇数?其实这是本题的一个重点(我打赌没有这个条件这道题就做不出来),这要从本题的二分查找思想谈起——
一开始,我们锁定空位在1~n-1的位置(l=0,r=n-1),接着开始二分,求出 mid=(l+r)/2 m i d = ( l + r ) / 2 的位置的座位情况:如果是空,就直接结束,如果不为空,则判断它与位置0的关系。这里就可以凸显奇数的重要性了:如果0~mid有奇数个位置,则mid+1~n-1就有偶数个位置,而且通过这样就可以得出以下结论:

①当两状况相同时,如果座位数为奇数,则该区域可能不存在空位置,但是剩余区域一定有一个空位置;如果座位数为偶数,则该区域一定有一个空位置;
②当两状况不相同时,如果座位数为偶数,则该区域可能不存在空位置,但是剩余区域一定有一个空位置;如果座位数为奇数,则该区域一定有一个空位置;

所以根据这些,我们可以不断的缩小范围,注意:当0~mid区间正常时,不正常的区间是mid+1~n-1
别忘了当函数返回2(即找到空位)时要即时结束程序。

◇源代码◇

/*Lucky_Glass*/
#include<cstdio>
#include<algorithm>
using namespace std;
int Query(int ans)
{
    char ret[20];
    printf("%d\n", ans);
    fflush(stdout);
    scanf("%s", ret);
    if(ret[0] == 'V') return 2;
    return ret[0] == 'M' ? 1 : 0;
}
int n;
int main()
{
    scanf("%d",&n);
    int res0=Query(0);
    if(res0==2) return 0;
    int l=0,r=n-1;
    while(true)
    {
        int mid=(l+r)>>1;
        int res_mid=Query(mid);
        if(res_mid==2) return 0;
        if(res_mid!=res0)
        {
            if(mid%2) l=mid+1;
            else r=mid;
        }
        else
        {
            if(mid%2) r=mid;
            else l=mid+1;
        }
    }
    Query(r);
    return 0;
}

The End

Thanks for reading!

- Lucky_Glass

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值