ASC45 Analogous Sets


题目描述:

Problem A. Analogous Sets
Input le: analogous.in
Output le: analogous.out
Time limit: 2 seconds
Memory limit: 512 mebibytes
For a set A of positive integers let us call A + A a multiset {x + y | x, y ∈ A, x ̸= y}.
Consider two sets A and B of the same size n containing positive integers. A and B are called analogous
if A + A and B + B are the same multisets. For example, {1, 4} and {2, 3} are analogous, because
A + A = B + B = {5}, but {1, 2, 5, 6} and {1, 3, 4, 6} are not, because A + A = {3, 6, 7, 7, 8, 11} and
B + B = {4, 5, 7, 7, 9, 10}.
Given n you have to nd two analogous sets of size n or detect that there are none.
Input
The input le contains multiple test cases, one on a line.
Each test case is an integer n on a line by itself (2 ≤ n ≤ 1000).
The last test case is followed by a zero that should not be processed.
Output
For each test case print Yes if there exist two dierent analogous sets of size n, or No if there are
none. If there exist such sets, the following two lines must contain n positive integers each and describe
the found sets.
If there are several possible pairs of analogous sets for some n, you can output any one.
Example
analogous.in analogous.out
2
3
0
Yes
1 4
2 3
No

题解:

好题 吧..
首先很容易发现4个的交叉.然后我们发现了一个大概6个或者8个的,发现不对.这时候就要考虑到轮换对称平衡感觉** 所以写出来是中心对称的感觉.
其实就是上下交叉重复. 想不出来什么好的并且直观有用的证法

重点:

轮换对称是一种很重要的对称. 轮流拷贝+2的幂次也是应该去想的

代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>

using namespace std;

int n;
vector<int> a[2];

void solve()
{
    int flag = 0;
    for(int i = 1; i <= 10; i++)
    {
        if((1 << i) == n)
        {
            flag = 1;
            break;
        }
    }
    if(flag == 0)
    {
        printf("No\n");
        return;
    }
    else
    {
        printf("Yes\n");
        a[0].clear();
        a[1].clear();
        a[0].push_back(1);
        a[0].push_back(4);
        a[1].push_back(2);
        a[1].push_back(3);
        for(int i = 2; (1 << i) <= n; i++)
        {
            int last = (1 << (i));
            int t = a[0].size();
            for(int j = 0; j < t; j++)
            {
                a[0].push_back(last + a[1][j]);
                a[1].push_back(last + a[0][j]);
            }
        }
        for(int i = 0; i < a[0].size(); i++)
        {
            printf("%d ", a[0][i]);
        }
        printf("\n");
        for(int i = 0; i < a[1].size(); i++)
        {
            printf("%d ", a[1][i]);
        }
        printf("\n");
    }
}

int main()
{
    //freopen("A.txt", "r", stdin);
    freopen("analogous.in", "r", stdin);
    freopen("analogous.out", "w", stdout);
    while(scanf("%d", &n) && n)
    {
        solve();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值