百度工程师所研究的 一种数据分配问题

问题简单描述如下:
N为大于1的自然数,
有一个序列{1,2,3,4 ... N^2}, 
(严格一点,应该用{Xi}表示序列,i为下标,上面就简单用下标代替序列元素了)
每n个元素合为一组,称为一“格”。划分后形式如下:
{[1,2,...,N], [N+1,...,2N], ..., [N(N-1)+1,...,N^2]}
将N^2个元素,分到N个格中,称做一次 “分配”。
现在要求将这N格中的数据重新分配,要求:
1.一次分配,共N个格,每格N个元素,一个元素只属于一格(平等原则);
2.在不同的分配中,任意2个格子之间,只允许一个元素相同(最小相似原则);
3.对一个N值,要完成N次分配(如果考虑最初的原始分配那就是N+1次分配);

例如 N=2 时,
序列{1,2,3,4}
初始划分为 
[[1 2] [3 4]]
2格的数据重新分配,2次分配如下:
[[1 3] [2 4]]   
[[1 4] [2 3]]
( 满足,不同分配之间的任意2个格中的元素只允许一个相同,
[1 3] 与 [2 3] 只有3相同。
[2 4] 与 [2 3] 只有2相同。
找到2次分配就算完成任务。) 

例如 N=3 时,
[[1 2 3] [4 5 6] [7 8 9]] 初始分配 
[[1 4 7] [2 5 8] [3 6 9]] 一次分配 
[[1 5 9] [2 6 7] [3 4 8]] 一次分配 
[[1 6 8] [2 4 9] [3 5 7]] 一次分配 

你来设计一种数据分配的机制,给定N,将初始序列,变换为N个不同的序列。
该机制,可以将数据分配到不同的网络节点上,有很大的实用价值。


有这样一个规律,当N= 2 3 5 7 11 等素数时,这种分配方案很容易找。
但是,当N为合数时,就变得困难了,N=4时是有解的,但其它的合数就不知道了。

对于n为素数的分配方式代码如下:

#include<iostream>
using namespace std;

int main(){
 cout<<"请输入一个素数N"<<endl;
 int n;
 cin>>n;
 int data[n][n];
 int num=1;
 for(int i=0;i<n;i++){
  for(int j=0;j<n;j++){
   data[i][j]=num;
   num++;   
  }  
 }
 int count=1;
 cout<<"最原始的分组为:"<<endl;
 for(int i=0;i<n;i++){
  cout<<'[';
  for(int j=0;j<n;j++){
   cout<<data[i][j]<<',';   
  }
  cout<<']'<<endl; 
 }
 for(int step=0;step<n;step++){
  cout<<endl<<"后一排数据比第一排数据向右平移的步数为: "<<step<<endl; 
     for(int i=0;i<n;i++){
      cout<<"第"<<count<<"个分组"<<endl; 
      cout<<'[';
      cout<<data[0][i]<<',';
   for(int j=1;j<n;j++){       
       cout<<data[j][(i+step*j)%n]<<',';              
   }
   cout<<']'<<endl;
   count++;      
  } 
 }
 return 0;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值