sgu 137 Funny Strings

39 篇文章 0 订阅
14 篇文章 0 订阅

题目描述:

137. Funny Strings

time limit per test: 0.5 sec.
memory limit per test: 4096 KB

Let's consider a stringof non-negative integers, containing N elements. Suppose these elementsare S1 S2 .. SN,in the order in which they are placed inside the string. Such a stringis called 'funny' if the string S1+1 S2S3 .. SN-1 SN -1can be obtained by rotating the first string (to the left or to the right)several times. For instance, the strings2 2 2 3 and 1 2 1 22 are funny, but the string 1 2 1 2 is not. Your taskis to find a funny string having N elements, for which thesum of its elements (S1+S2+..+SN)is equal to K.

Input

The input containstwo integers: N (2<=N<=1000) and K (1<=K<=30000).Moreover, GCD(N,K)=1 (it can be proven that this is a necessarycondition for a string to be funny).

Output

You should outputone line containing the elements of the funny string found. These integersshould be separated by blanks.

Hint

GCD(A,B) = the greatestcommon divisor of A and B.
The 'funny'strings are also named Euclid strings in several papers.

Sample Input

9 16

Sample Output

1 2 2 2 1 2 2 2 2


题目要求你找出一个长度为n的序列,满足其和值为k,然后把该序列的头减1,尾加1,要求得到的新序列可以由原序列经平移得到。题目保证n和k互质。


如果我们能够将k<n的姐求出,那么此题就可解。因为假设 k=m*n+r;

那么如果我们知道r的解,将这个解序列的每个值都加上m,仍然符合条件,而且是k的一个解。


将序列编号 0,1,2,3,.........,n-1。

那么编号为0的地方放0,编号为n-1的地方放1,就是

                                编号 0   1   2   3   ...    n-1

                                数值 0   X  X   X   ...     1

为X表示未知值,将头尾变化之后有

                                编号 0   1   2   3   ...    n-1

                                数值 0   X  X   X   ...     1

                           变化后  1   X  X   X   ...      0

我们知道这个新序列可以由老的序列平移得到,假设向右平移d个位置。

那么我们知道原序列为d的位置值为1.即:

                                编号 0   1   2   3   ...   d    ....    n-1

                                数值 0   X  X   X   ...   1   ....      1

                           变化后  1   X  X   X   ...    1  ....       0

那么就能推出在位置d,2d 3d ,kd位置为1。

所以我们有 k*d = n-1 (mod n) ->  k*d=-1(mod n)

we have gcd(k,n)=1 so we can find a K 满足 k*K = 1 (mod n)


所以 d=-K (mod n) ;

问题迎刃而解 。。。


但是此问题的必要性我还不会证,求大牛赐教哈。。。


贴代码时间:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<algorithm>
#include<vector>
#include<cstdlib>

#define inf 0xfffffff
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define FOR(a,b) for(int a=1;a<=(b);(a)++)

using namespace std;
int const nMax = 1010;
int const base = 10;
typedef int LL;
typedef pair<LL,LL> pij;

//    std::ios::sync_with_stdio(false);

int ext_gcd(int a,int b,int &x,int &y){
    if(b==0){
        x=1;y=0;return a;
    }
    int d=ext_gcd(b,a%b,y,x);
    y-=(a/b)*x;
    return d;
}

int inv(int a,int n){
    int x,y;
    int d=ext_gcd(a,n,x,y);
    return d==1?(x+n)%n:-1;
}

int n,K;
int ans[nMax];
int main(){
    cin>>n>>K;
    int add=K/n;
    K%=n;
    int k=inv(K,n);
    int d=(n-k)%n;
    FOR(i,K){
        ans[(d*i)%n]=1;
    }
    for(int i=0;i<n;i++)printf("%d ",ans[i]+add);
    printf("\n");
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值