题目描述:
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;
}