Good Bye 2019补题记录

Good Bye 2019补题记录

A. Card Game

题目描述
Two players decided to play one interesting card game.

There is a deck of n cards, with values from 1 to n. The values of cards are pairwise different (this means that no two different cards have equal values). At the beginning of the game, the deck is completely distributed between players such that each player has at least one card.

The game goes as follows: on each turn, each player chooses one of their cards (whichever they want) and puts on the table, so that the other player doesn’t see which card they chose. After that, both cards are revealed, and the player, value of whose card was larger, takes both cards in his hand. Note that as all cards have different values, one of the cards will be strictly larger than the other one. Every card may be played any amount of times. The player loses if he doesn’t have any cards.

For example, suppose that n=5, the first player has cards with values 2 and 3, and the second player has cards with values 1, 4, 5. Then one possible flow of the game is:

The first player chooses the card 3. The second player chooses the card 1. As 3>1, the first player gets both cards. Now the first player has cards 1, 2, 3, the second player has cards 4, 5.

The first player chooses the card 3. The second player chooses the card 4. As 3<4, the second player gets both cards. Now the first player has cards 1, 2. The second player has cards 3, 4, 5.

The first player chooses the card 1. The second player chooses the card 3. As 1<3, the second player gets both cards. Now the first player has only the card 2. The second player has cards 1, 3, 4, 5.

The first player chooses the card 2. The second player chooses the card 4. As 2<4, the second player gets both cards. Now the first player is out of cards and loses. Therefore, the second player wins.

Who will win if both players are playing optimally? It can be shown that one of the players has a winning strategy.

Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤100). The description of the test cases follows.

The first line of each test case contains three integers n, k1, k2 (2≤n≤100,1≤k1≤n−1,1≤k2≤n−1,k1+k2=n) — the number of cards, number of cards owned by the first player and second player correspondingly.

The second line of each test case contains k1 integers a1,…,ak1 (1≤ai≤n) — the values of cards of the first player.

The third line of each test case contains k2 integers b1,…,bk2 (1≤bi≤n) — the values of cards of the second player.

It is guaranteed that the values of all cards are different.

Output
For each test case, output “YES” in a separate line, if the first player wins. Otherwise, output “NO” in a separate line. You can print each letter in any case (upper or lower).
Note
In the first test case of the example, there is only one possible move for every player: the first player will put 2, the second player will put 1. 2>1, so the first player will get both cards and will win.

In the second test case of the example, it can be shown that it is the second player who has a winning strategy. One possible flow of the game is illustrated in the statement.

样例输入
2
2 1 1
2
1
5 2 3
2 3
1 4 5
样例输出
YES
NO

题意
是否存在n
思路
水题

#pragma GCC optimize(3,"Ofast","inline")  	//G++
#include
 
#define TEST freopen("C:\\Users\\hp\\Desktop\\ACM\\in.txt","r",stdin);
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 
using namespace std;
typedef long long ll;
 
const int inf=0x3f3f3f3f;
const int mod=1e5+7;
const int maxn = 1e6+5;

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int flag=0;
        int n,a,b;
        cin>>n>>a>>b;
        for(int i=1;i<=a;i++)
        {
            int x;
            cin>>x;
            if(x==n)
                flag=1;
        }
        for(int i=1;i<=b;i++)
        {
            int x;
            cin>>x;
        }
        if(flag)
            cout<<"YES\n";
        else
            cout<<"NO\n";
    }
}

B. Interesting Subarray

题目描述
For an array a of integers let’s denote its maximal element as max(a), and minimal as min(a). We will call an array a of k integers interesting if max(a)−min(a)≥k. For example, array [1,3,4,3] isn’t interesting as max(a)−min(a)=4−1=3<4 while array [7,3,0,4,3] is as max(a)−min(a)=7−0=7≥5.

You are given an array a of n integers. Find some interesting nonempty subarray of a, or tell that it doesn’t exist.

An array b is a subarray of an array a if b can be obtained from a by deletion of several (possibly, zero or all) elements from the beginning and several (possibly, zero or all) elements from the end. In particular, an array is a subarray of itself.

Input
The first line contains integer number t (1≤t≤10000). Then t test cases follow.

The first line of each test case contains a single integer n (2≤n≤2⋅105) — the length of the array.

The second line of each test case contains n integers a1,a2,…,an (0≤ai≤109) — the elements of the array.

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output
For each test case, output “NO” in a separate line if there is no interesting nonempty subarray in a.

Otherwise, output “YES” in a separate line. In the next line, output two integers l and r (1≤l≤r≤n) — bounds of the chosen subarray. If there are multiple answers, print any.

You can print each letter in any case (upper or lower).
Note
In the second test case of the example, one of the interesting subarrays is a=[2,0,1,9]: max(a)−min(a)=9−0=9≥4.

样例输入
3
5
1 2 3 4 5
4
2 0 1 9
2
2019 2020
样例输出
NO
YES
1 4
NO

翻译成中文
给出一个数列,要求找出一段连续的子数列满足这个子数列的最大值与最小值之差不小于其元素个数。
思路
水题

#pragma GCC optimize(3,"Ofast","inline")  	//G++
#include
 
#define TEST freopen("C:\\Users\\hp\\Desktop\\ACM\\in.txt","r",stdin);
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 
using namespace std;
typedef long long ll;
 
const int inf=0x3f3f3f3f;
const int mod=1e5+7;
const int maxn = 1e6+5;
 
int a[maxn];
int n;
void solve()
{
    for(int i=1;i<=n-1;i++)
    {
        if(abs(a[i]-a[i+1])>=2)
        {
            cout<<"YES\n";
            cout<<i<<" "<<i+1<<"\n";
            return ;
        }
    }
    cout<<"NO\n";
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        solve();
    }
}

C. Make Good

题目描述
Let’s call an array a1,a2,…,am of nonnegative integer numbers good if a1+a2+⋯+am=2⋅(a1⊕a2⊕⋯⊕am), where ⊕ denotes the bitwise XOR operation.

For example, array [1,2,3,6] is good, as 1+2+3+6=12=2⋅6=2⋅(1⊕2⊕3⊕6). At the same time, array [1,2,1,3] isn’t good, as 1+2+1+3=7≠2⋅1=2⋅(1⊕2⊕1⊕3).

You are given an array of length n: a1,a2,…,an. Append at most 3 elements to it to make it good. Appended elements don’t have to be different. It can be shown that the solution always exists under the given constraints. If there are different solutions, you are allowed to output any of them. Note that you don’t have to minimize the number of added elements!. So, if an array is good already you are allowed to not append elements.

Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤10000). The description of the test cases follows.

The first line of each test case contains a single integer n (1≤n≤105) — the size of the array.

The second line of each test case contains n integers a1,a2,…,an (0≤ai≤109) — the elements of the array.

It is guaranteed that the sum of n over all test cases does not exceed 105.

Output
For each test case, output two lines.

In the first line, output a single integer s (0≤s≤3) — the number of elements you want to append.

In the second line, output s integers b1,…,bs (0≤bi≤1018) — the elements you want to append to the array.

If there are different solutions, you are allowed to output any of them.
Note
In the first test case of the example, the sum of all numbers is 12, and their ⊕ is 6, so the condition is already satisfied.

In the second test case of the example, after adding 4,4, the array becomes [8,4,4]. The sum of numbers in it is 16, ⊕ of numbers in it is 8.
题目描述
一个数组[a1,a2,…,am]为 good 的条件是 a1+a2+⋯+am=2⋅(a1⊕a2⊕⋯⊕am),其中 ⊕ 表示异或。
最多加上3个数(可以相同)使得数组为 good,任选一种方案输出。
思路
水题

样例输入
3
4
1 2 3 6
1
8
2
1 1
样例输出
0

2
4 4
3
2 6 2

#pragma GCC optimize(3,"Ofast","inline")  	//G++
#include
 
#define TEST freopen("C:\\Users\\hp\\Desktop\\ACM\\in.txt","r",stdin);
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 
using namespace std;
typedef long long ll;
 
const ll inf=0x3f3f3f3f;
const ll mod=1e5+7;
const ll maxn = 1e6+5;
 
main()
{
    ll T;
    cin>>T;
    while(T--)
    {
        ll n;
        cin>>n;
        ll sum=0,sum1=0;
        for(ll i=1;i<=n;i++)
        {
            ll x;
            cin>>x;
            sum+=x;
            sum1^=x;
        }
        if(sum1*2==sum)
        {
            cout<<"0\n\n";
        }
        else
        {
            cout<<"2\n";
            cout<<sum1<<" "<<sum1+sum<<"\n";
        }
    }
}

D. Strange Device

题目描述
This problem is interactive.

We have hidden an array a of n pairwise different numbers (this means that no two numbers are equal). You can get some information about this array using a new device you just ordered on Amazon.

This device can answer queries of the following form: in response to the positions of k different elements of the array, it will return the position and value of the m-th among them in the ascending order.

Unfortunately, the instruction for the device was lost during delivery. However, you remember k, but don’t remember m. Your task is to find m using queries to this device.

You can ask not more than n queries.

Note that the array a and number m are fixed before the start of the interaction and don’t depend on your queries. In other words, interactor is not adaptive.

Note that you don’t have to minimize the number of queries, and you don’t need to guess array a. You just have to guess m.

Input
The first line contains two integers n and k (1≤k

It is guaranteed that number m satisfies 1≤m≤k, elements a1,a2,…,an of the array satisfy 0≤ai≤109, and all of them are different.

Interaction
You begin the interaction by reading n and k.

To ask a question about elements on positions x1,x2,…,xk, in a separate line output

? x1 x2 x3 … xk
Numbers in the query have to satisfy 1≤xi≤n, and all xi have to be different. Don’t forget to ‘flush’, to get the answer.

In response, you will receive two integers pos and apos — the position in the array a of the m-th in ascending order element among ax1,ax2,…,axk, and the element on this position.

In case your query is invalid or you asked more than n queries, the program will print −1 and will finish interaction. You will receive a Wrong answer verdict. Make sure to exit immediately to avoid getting other verdicts.

When you determine m, output

! m
After printing a query do not forget to output end of line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

fflush(stdout) or cout.flush() in C++;
System.out.flush() in Java;
flush(output) in Pascal;
stdout.flush() in Python;
see documentation for other languages.
第一次做交互题
样例输入
4 3
4 9
4 9
4 9
1 2
样例输出
? 2 3 4
? 1 3 4
? 1 2 4
? 1 2 3
! 3
Note
In the example, n=4, k=3, m=3, a=[2,0,1,9].
题目大意:
有一个两两值互不相同的数组,但是你不知道这个数组的值,有一个机器,你询问 k 个下标,他会返回这数组中这 k 个下标对应的数 按升序排序后的第 m 个的下标和值。你现在不知道 m,你可以通过问 不多于 n 个问题,每个问题的形式为 :输出 ? x_1 x_2 x_3 … x_k,机器会返回这些下标在数组中对应的数,排序后的第m个的下标和值。求 m。
思路:
对数组的前k + 1个元素询问k + 1次,结果会出现两个数字,分别是第m大的数和第m + 1大的数。并且,第m + 1大的数将出现m次,第m大的数将出现k + 1 - m次。因此,统计较大的那个数出现的次数即是答案。

 #pragma GCC optimize(3,"Ofast","inline")  	//G++
#include
 
#define TEST freopen("C:\\Users\\hp\\Desktop\\ACM\\in.txt","r",stdin);
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 
using namespace std;
typedef long long ll;
 
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn = 1e6+5;
int main()
{
    map<int,int>mp;
    int n,k,m;
    cin>>n>>k;
    for(int i=1;i<=k+1;i++)
    {
        cout<<"? ";
        for(int j=1;j<=k+1;j++)
        {
            if(i!=j) cout<<j<<" ";
        }
        cout<<"\n";
        cout.flush();
        int x,y;
        cin>>x>>y;
        mp[y]++;
    }
    cout<<"! "<<(*mp.rbegin()).second<<"\n";
}

E. Divide Points(奇偶分类构造)

题目描述
You are given a set of n≥2 pairwise different points with integer coordinates. Your task is to partition these points into two nonempty groups A and B, such that the following condition holds:

For every two points P and Q, write the Euclidean distance between them on the blackboard: if they belong to the same group — with a yellow pen, and if they belong to different groups — with a blue pen. Then no yellow number is equal to any blue number.

It is guaranteed that such a partition exists for any possible input. If there exist multiple partitions, you are allowed to output any of them.

Input
The first line contains one integer n (2≤n≤103) — the number of points.

The i-th of the next n lines contains two integers xi and yi (−106≤xi,yi≤106) — the coordinates of the i-th point.

It is guaranteed that all n points are pairwise different.

Output
In the first line, output a (1≤a≤n−1) — the number of points in a group A.

In the second line, output a integers — the indexes of points that you include into group A.

If there are multiple answers, print any.
样例输入
6
2 5
0 3
-4 -1
-5 -4
1 0
3 -1
样例输出
1
6
Note
In the first example, we set point (0,0) to group A and points (0,1) and (1,0) to group B. In this way, we will have 1 yellow number 2–√ and 2 blue numbers 1 on the blackboard.

In the second example, we set points (0,1) and (0,−1) to group A and points (−1,0) and (1,0) to group B. In this way, we will have 2 yellow numbers 2, 4 blue numbers 2–√ on the blackboard.
题目大意
将二维坐标平面上的点分成两组,使得同一组的点之间的欧几里得距离不等于不同组之间的欧几里得距离。
思路
首先按在坐标(x,y)的奇偶性将所有点划分到4个桶:00,01,10,11;1代表奇数,0代表偶数。
00和11一个桶,01和10一个桶,桶内间的点的距离定为偶数,不同桶直接定为奇数。
如果只包含一个桶,可以旋转坐标系,类似切比雪夫距离->曼哈顿距离,直到两个桶都有元素为止

#pragma GCC optimize(3,"Ofast","inline")  	//G++
#include
 
#define TEST freopen("C:\\Users\\hp\\Desktop\\ACM\\in.txt","r",stdin);
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 
using namespace std;
typedef long long ll;
 
const ll inf=0x3f3f3f3f;
const ll INF=0x7fffffffffffffff;
const ll mod=1e9+7;
const ll maxn = 1e6+5;
ll n;
ll a[maxn],b[maxn];
void pri(vector<ll>a)
{
    cout<<a.size()<<"\n";
    for(auto v:a)
    {
        cout<<v<<" ";
    }
    cout<<"\n";
}
void solve()
{
    while(true)
    {
        ll ou=0,ji=0;
        for(ll i=1; i<=n; i++)
        {
            if((abs(a[i]+b[i]))&1) ji++;
            else ou++;
        }
//        debug(ji);
//        debug(ou);
        if(ji!=0&&ou!=0)
        {
            vector<ll>ans;
            for(ll i=1; i<=n; i++)
            {
                if((abs(a[i]+b[i]))&1)
                {
                    ans.push_back(i);
                }
            }
            pri(ans);
            return ;
        }
        else
        {
            if(ou==0)
            {
                for(ll i=1; i<=n; i++)
                {
                    a[i]++;
                }
            }
            for(ll i=1; i<=n; i++)
            {
                ll x=a[i]+b[i];
                ll y=a[i]-b[i];
                a[i]=x>>1;
                b[i]=y>>1;
            }
        }
    }
}
main()
{
    cin>>n;
    for(ll i=1; i<=n; i++)
    {
        cin>>a[i]>>b[i];
    }
    solve();
}

将一个点(x,y)的坐标变为(x+y,x−y)后,原坐标系中的曼哈顿距离 == 新坐标系中的切比雪夫距离
将一个点(x,y)的坐标变为(x+y)/2, (x−y)/2)后,原坐标系中的切比雪夫距离 == 新坐标系中的曼哈顿距离

G. Subset with Zero Sum

题目描述
You are given n integers a1,a2,…,an, such that for each 1≤i≤n holds i−n≤ai≤i−1.

Find some nonempty subset of these integers, whose sum is equal to 0. It can be shown that such a subset exists under given constraints. If there are several possible subsets with zero-sum, you can find any of them.

Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤106). The description of the test cases follows.

The first line of each test case contains a single integer n (1≤n≤106).

The second line of each test case contains n integers a1,a2,…,an (i−n≤ai≤i−1).

It is guaranteed that the sum of n over all test cases does not exceed 106.

Output
For each test case, output two lines.

In the first line, output s (1≤s≤n) — the number of elements in your subset.

In the second line, output s integers i1,i2,…,is (1≤ik≤n). All integers have to be pairwise different, and ai1+ai2+⋯+ais has to be equal to 0. If there are several possible subsets with zero-sum, you can find any of them.
样例输入
2
5
0 1 2 3 4
4
-3 1 1 1
样例输出
1
1
4
1 4 3 2
Note
In the first example, we get sum is a1=0.
In the second example, we get sum is a1+a4+a3+a2=0.
题目大意
有一个数组a,满足i−n≤ai≤i−1,求该序列的一个子集使得这个子集和为0。
思路
由 i−n≤ai≤i−1. 我们可以得到 i-ai 是在1 到 n之间的。然后我们让 i 连向 i-a[i] ,这样,如果我们能找到一个环,那么这个环的元素之和为0,不难证明,所以找环即可。

#pragma GCC optimize(3,"Ofast","inline")  	//G++
#include

#define TEST freopen("C:\\Users\\hp\\Desktop\\ACM\\in.txt","r",stdin);
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

using namespace std;
typedef long long ll;

const int inf=0x3f3f3f3f;
const ll INF=0x7fffffffffffffff;
const int mod=1e9+7;
const int maxn = 1e6+5;
vector<int>edge[maxn];
int vis[maxn],a[maxn];
int n,flag=1;
void pri(vector<int>a)
{
    cout<<a.size()<<"\n";
    for(auto v:a)
    {
        cout<<v<<" ";
    }
    cout<<"\n";
}
void add(int x,int y)
{
    edge[x].push_back(y);
}
void dfs(int x)
{
    vis[x]=1;
    for(int i=0; i<edge[x].size(); i++)
    {
        int v=edge[x][i];
        if(vis[v]&&flag)
        {
            vector<int>ans;
            int net=edge[v][0];
            ans.push_back(v);
            while(net!=v)
            {
                ans.push_back(net);
                net=edge[net][0];
            }
            flag=0;
            pri(ans);
            return ;
        }
        dfs(v);
    }
}
int main()
{
    ios;
    int T;
    cin>>T;
    while(T--)
    {
        flag=1;
        cin>>n;
        for(int i=1; i<=n; i++)
        {
            edge[i].clear();
        }
        for(int i=1; i<=n; i++)
        {
            vis[i]=0;
            cin>>a[i];
            add(i,i-a[i]);
        }
        for(int i=1; i<=n&&flag; i++)
        {
            if(!vis[i])
            {
                dfs(i);
            }
        }
    }
}

你可能感兴趣的:(补题)