codechef Partition the numbers(思维)

Description

You are given two integers x and N. Consider all integers between 1 and N inclusive, except x. We want to partition these integers into two disjoint sets (each integer has to appear in exactly one set) such that the sums of numbers in these sets are equal.

Find one valid partition or determine that it doesn’t exist.

Input

The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first and only line of each test case contains two space-separated integers x and N.

Output

For each test case:

If there’s no way to partition the numbers into two sets with equal sums, print a single line containing the string “impossible” (without quotes).
Otherwise, print a single line containing a string with length N.
The x-th character of this string should be ‘2’.
For each valid i ≠ x, the i-th character of this string should be ‘0’ if number i should be in the first set or ‘1’ if it should be in the second set.

Constraints

1 ≤ T ≤ 10,000
2 ≤ N ≤ 1,000,000
1 ≤ x ≤ N
1 ≤ sum of N in all test cases ≤ 1,000,000

Example

Input:

3
2 4
5 5
1 2

Output:

0201
01102
impossible

题目大意

从1-n中去除x,判断剩下的数能否分成和相等的两部分,如果可以输出分组方法;否则输出impossible.

解题思路

先计算去除x之后每部分的和应为多少,然后从n->1进行遍历,如果满足当前数i不为x且sum>=i,则sum-=i并且加上分组标记,但是当sum-i等于x时,代表当前分组不可行,则需要回退。

代码实现

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 1000007
int mark[maxn];
int main()
{
    ios::sync_with_stdio(false);
    int T;
    ll x,n;
    cin>>T;
    while(T--)
    {
        memset(mark,0,sizeof(mark));
        cin>>x>>n;
        ll sum=(n*(n+1)/2-x);
        if(sum%2!=0)
            cout<<"impossible"<<endl;
        else
        {
            sum/=2;
            mark[x]=2;
            for(ll i=n;i>=1;i--)
            {
                if(i!=x&&sum-i>=0)
                {
                    sum-=i;
                    mark[i]=1;
                    if(sum==x)
                    {
                        sum+=i;
                        mark[i]=0;
                    }
                    if(sum==0) break;
                }
            }
            if(sum==0)
            {
                for(ll i=1;i<=n;i++)
                    cout<<mark[i];
                cout<<endl;
            }
            else
                cout<<"impossible"<<endl;
        }
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值